组件单元测试服务调用在 afterviewinit 中解决

component unit testing services call resolved in the afterviewinit

我有一个实现 afterviewinit 的组件,在 ngAfterViewInit 中我有一些服务调用和一个检查活动选项卡的调用,但我正在努力设置我的单元测试:

export class SomeComponent implements OnInit, AfterViewInit{
@ViewChild('tabGroup') tabGroup: MatTabGroup;

 ngOnInit(): void {}
 ngAfterViewInit(): void {
 const label = this.tabGroup._tabs.find((x: MatTab) => x.isActive).textLabel;
 
 //Service Call that use the label
 }
}

在我的测试中:

 describe('SomeComponent', () => {
        let component: SomeComponent;
        let fixture: ComponentFixture<SomeComponent>;
        
        
        beforeEach(waitForAsync(()=>{
        
        TestBed.configureTestingModule( declarations: [
                    SomeComponent,]
                    imports:[ MatTabsModule,]).compileComponents();
    });
                    
                                 
beforeEach(() => {
    fixture = TestBed.createComponent(someComponent);
    component = fixture.componentInstance;
    Object.defineProperty(component, 'tabs', { value: [], isActive: true});
    fixture.detectChanges();
  });

        it('should be created', () => {
            expect(component).toBeTruthy();
        });});

测试 运行 好的,但我收到此错误:AfterAll TypeError: Cannot read property 'textLabel' of undefined

我试过使用:

afterEach(() => {
  fixture.destroy();
});

似乎已经解决了第一个测试,但我只是想知道是否有更好的方法来做。 PS:基本上我的问题是我应该如何模拟在 ngAfterViewInit 中设置的对象,例如选项卡是 viewchild 此致

因为MatTabGroup是一个依赖,我建议在测试中模拟它。 为此,可以使用 ng-mocks 等测试库。

带有解决方案的沙箱:https://codesandbox.io/s/cool-chebyshev-wp7mr?file=/src/test.spec.ts

describe('SomeComponent', () => {
  // keep SomeComponent and mocks MatTabsModule
  beforeEach(() => MockBuilder(SomeComponent).mock(MatTabsModule));

  it('should be created', () => {
    // now we say that MatTabGroup._tabs should be a fake value
    MockInstance(MatTabGroup, '_tabs', new QueryList<MatTab>()).reset([
      // the value has 1 element
      // it is a fake MatTab with the desired value.
      MockService(MatTab, {
        isActive: true,
      }),
    ]);
    const component = MockRender(SomeComponent).point.componentInstance;

    expect(component).toBeTruthy();
  });
});