繁体   English   中英

Angular 测试失败,在动态生成的子组件中出现 pipe

[英]Angular test fails with pipe in dynamically generated child component

我有一个 angular 组件,它用作其他一些组件的外观。 这是使用 ComponentFactoryResolver 实现的。 当我将 pipe 引入其中一个生成的组件时,我的单元测试开始以一种奇怪的方式失败。

我希望有人能够解释为什么它会以这种方式失败?

        Failed: NG0302: The pipe 'displayValue' could not be found!. Find more at https://angular.io/errors/NG0302
        error properties: Object({ code: '302' })
        Error: NG0302: The pipe 'displayValue' could not be found!. Find more at https://angular.io/errors/NG0302
            at getPipeDef$1 (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:25738:1)
            at ɵɵpipe (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:25695:1)        
            at UsesPipeComponent_Template (ng:///UsesPipeComponent.js:7:9)
            at executeTemplate (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9544:1)
            at renderView (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9351:1)     
            at renderComponent (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10626:1)
            at renderChildComponents (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9216:1)
            at renderView (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9376:1)     
            at ComponentFactory$1.create (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:25079:1)
            at ViewContainerRef.createComponent (node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:23118:1)
Chrome 88.0.4324.190 (Windows 10): Executed 1 of 1 (1 FAILED) (0.082 secs / 0.074 secs)

我的测试

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        DisplayValuePipe
      ],
      imports: [CommonModule]
    }).compileComponents();
  }));

  it('should create the app', waitForAsync(() => {
    const fixture = TestBed.createComponent(AppComponent);
    fixture.componentInstance.title = 'testing';

    fixture.detectChanges();

    const app = fixture.componentInstance;
    console.log(fixture.nativeElement.innerHTML);
    expect(app).toBeTruthy();
  }));

应用组件

@Component({
  selector: 'app-root',
  template: `<div>{{"test" | displayValue}}</div><ng-template #control></ng-template>`,
})
export class AppComponent implements AfterViewInit {
  title = 'testing-pipe';

  @ViewChild('control', { read: ViewContainerRef })
  public controlView: ViewContainerRef | undefined;

  constructor(private factoryResolver: ComponentFactoryResolver) { }

  ngAfterViewInit(): void {
    const factory = this.factoryResolver.resolveComponentFactory(UsesPipeComponent);
    this.controlView?.clear();
    const comp = this.controlView?.createComponent(factory);
    comp?.changeDetectorRef.detach();
    comp?.changeDetectorRef.detectChanges();
  }
}

用途-管道

@Component({
  selector: 'app-uses-pipe',
  template: `{{"test" | displayValue}}`,
})
export class UsesPipeComponent {
  constructor() { }
}

pipe

@Pipe({
  name: 'displayValue'
})
export class DisplayValuePipe implements PipeTransform {
  transform(value: string, ...args: unknown[]): string {
    return value.toUpperCase();
  }
}

我是如何解决的

我错过了TestBed.configureTestModule动态组件的声明,如下所示:

beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [
        AppComponent,
        DisplayValuePipe,
        UsesPipeComponent // this one is required
      ],
      imports: [CommonModule]
    }).compileComponents();
  }));

这是有道理的,因为 TestBed 否则不会知道该组件,但是,如果 TestBed 没有注册它,我看不到测试是如何失败的,因为pipe子组件中使用。

任何有关它为何以这种方式失败的见解将不胜感激!


我也在 github 上发布了这个问题,有人回复了一个答案: https://github.com/angular/angular/issues/41083

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM