组件单元测试服务调用在 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();
});
});
我有一个实现 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();
});
});