我有一个组件,看起来像这样:
export class MyComponent {
myattr: boolean = true;
constructor(public myService: MyService) {
this.myService.stateUpdate.subscribe((event: number) => {
this.myattr = event == 10;
});
}
服务:
export class MyService {
stateUpdate: EventEmitter<number> = new EventEmitter<number>();
onSomeEvent(): void {
this.stateUpdate.emit(130);
}
}
我的单元测试尝试:
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
component.myService = new MyService();
});
it("emitting 130 should set myattr to false", async()=>{
component.myService.stateUpdate.subscribe((event: number) => {
expect(event).toEqual(130); // this is detected correctly
})
component.myService.onSomeEvent();
fixture.whenStable();
expect(component.myattr).toEqual(false); // this does not work
});
基本上,我想测试当subscribe
内的任何代码完成执行时会发生什么。我该怎么做呢?
在您的示例中,您创建了service,并在组件已经创建之后将其分配给myService属性,因此构造函数中的订阅是在服务的另一个实例上进行的。您可以在测试文件中创建服务的实例或模拟,并在配置测试平台时通过MyService令牌提供它。这样以后你就可以访问那个实例并在它上面发出事件
您必须在fixture.whenStable().then()
it("emitting 130 should set myattr to false", async(()=>{
component.myService.onSomeEvent();
fixture.whenStable().then(() => {
expect(component.myattr).toEqual(false);
});
});
注意,Angular的async()
被waitForAsync()
取代了
在Angular官方文档中有一整节是关于常见测试场景的,可能会有所帮助:
https://angular.io/guide/testing-components-scenarios
在您的特殊情况下,请查看以下两个小节,以获得带有示例的完整解释:
https://angular.io/guide/testing-components-scenarios component-with-a-dependency
https://angular.io/guide/testing-components-scenarios component-with-async-service
有不同的方法,但我通常做的是提供一个带有测试主题的服务存根来发出值,然后在测试用例中使用async关键字,这样我就可以期待发出时的结果。