How can I check the result of a DOM injection using ViewContainerRef in angular 2?

I have a directive:

@Directive({ selector: 'input[type=file][ngModel], input[type=file][formControlName], input[type=file][formControl]', host: {'(change)': 'filesSelected($event.target.files)', '(blur)': 'onTouched()'}, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef( () => FileValueAccessor), multi: true }] }) export class FileValueAccessor implements ControlValueAccessor { onChange = (_) => {}; onTouched = () => {}; fileListComponent: ComponentRef<FileUploadListComponent>; files: File[] = []; constructor( private _renderer: Renderer, private _elementRef: ElementRef, private resolver: ComponentFactoryResolver, private viewContainer: ViewContainerRef) { const factory = this.resolver.resolveComponentFactory(FileUploadListComponent); this.fileListComponent = this.viewContainer.createComponent(factory); this.fileListComponent.instance.removeFileCb = (file) => this.removeFile(file); } removeFile(file) { this.files = this.files.filter((f: File): Boolean => f !== file); this.filesUpdated(); } writeValue(value): void { } filesSelected(files: FileList) { for(let i in files) { const file = files[i]; if (isFile(file) && this.files.findIndex((f: File) => f.name === file.name && f.size === file.size) === -1) { this.files.push(file); } } this.filesUpdated(); } filesUpdated() { this.fileListComponent.instance.files = this.files; this.onChange(this.files); } registerOnChange(fn: (_: FileList) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this._renderer.setElementProperty(this._elementRef.nativeElement, 'disabled', isDisabled); } } 

What I'm trying to test like this:

 beforeEach(() => { fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should update files', async(inject([FileValueAccessor, ViewContainerRef], (fileAccesser: FileValueAccessor, viewContainer: ViewContainerRef) => { const files = Array(8).fill(getFile(randomValidFileName())) fileAccesser.files = files; fileAccesser.filesUpdated(); fixture.detectChanges(); expect(fixture.elementRef.nativeElement.querySelectorAll('app-file-upload-list-item').length).toBe(8); }))) 

But I get

Error: not implemented on this.fileListComponent = this.viewContainer.createComponent (factory); from directive

It is worth noting that the constructor of the directive is executed twice, and this is the second time an error occurs.

+6
source share

Source: https://habr.com/ru/post/1012565/


All Articles