Angular 使用组件 ngOnInit 时单元测试用例失败

Angular unit test case failing while using component ngOnInit

我正在使用 angular 7,在使用 component.ngOnInit()fixture.detectchanges() 时无法 运行 单元测试用例。如果删除 component.ngOnInit()fixture.detectchanges() 则测试用例通过但我想检测间谍后的变化。

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AppTestingModule, EffectsModule.forRoot([NodeEffects])],
      declarations: [SidenavComponent],
      schemas: [NO_ERRORS_SCHEMA],
      providers: [ApiNodesService]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SidenavComponent);
    component = fixture.componentInstance;
    browsingService = TestBed.get(BrowsingFilesService);
    apiNodesService = TestBed.get(ApiNodesService);
    appConfig = TestBed.get(AppConfigService);
    // appConfigSpy = spyOn(appConfig, 'get').and.returnValue([navItem]);
  });



  it('check getDocLibraries method is called', () => {
    spyOn(component, 'getDocLibraries');
    fixture.detectChanges();    
    component.ngOnInit();
    component.getDocLibraries();
    fixture.whenStable().then(data => {
      const debugUlElement = fixture.debugElement.query(By.css('ul.sidenav-menu_sub'));
      const nativeUlElement: HTMLUListElement = debugUlElement.nativeElement;
      expect(nativeUlElement.childElementCount).toEqual(1);
    });
  });
  });

错误信息: TypeError: Cannot convert undefined or null to object at Function.keys (<anonymous>) at SidenavComponent../src/app/components/sidenav/sidenav.component.ts.SidenavComponent.buildMenu (http://localhost:9876/src/app/components/sidenav/sidenav.component.ts?:93:19) at SidenavComponent../src/app/components/sidenav/sidenav.component.ts.SidenavComponent.ngOnInit (http://localhost:9876/src/app/components/sidenav/sidenav.component.ts?:76:28) at UserContext.<anonymous> (http://localhost:9876/src/app/components/sidenav/sidenav.component.spec.ts?:103:15)

您应该将规范包装在 async 中并将 detectChanges 移到 whenStable 中。

  it('check getDocLibraries method is called', async(() => {
    spyOn(component, 'getDocLibraries');
    component.getDocLibraries();
    fixture.whenStable().then(()=> {
      fixture.detectChanges();
      const debugUlElement = fixture.debugElement.query(By.css('ul.sidenav-menu_sub'));
      const nativeUlElement: HTMLUListElement = debugUlElement.nativeElement;
      expect(nativeUlElement.childElementCount).toEqual(1);
    });
    component.ngOnInit();
  }));

注意:你有一组额外的'});'最后呢?

你也可以使用 fakeAsync & tick 而不是 async & whenStable

  it('check getDocLibraries method is called', fakeAsync(() => {
    spyOn(component, 'getDocLibraries');
    component.getDocLibraries();
    component.ngOnInit();
    tick();
    fixture.detectChanges();
    const debugUlElement = fixture.debugElement.query(By.css('ul.sidenav-menu_sub'));
    const nativeUlElement: HTMLUListElement = debugUlElement.nativeElement;
    expect(nativeUlElement.childElementCount).toEqual(1);
  }));