如何在角度2中测试使用ViewContainerRef注入DOM的结果?

时间:2016-11-22 14:47:06

标签: javascript angular typescript jasmine

我有一个指令:

@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);
  }
}

我正试图这样测试:

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);
})))

但我得到了

  

错误:未实现this.fileListComponent =   this.viewContainer.createComponent(工厂);来自指令

值得注意的是,指令构造函数执行了两次,这是第二次发生错误。

0 个答案:

没有答案