编辑:我最终解决了这个问题,所以请参考下面的帖子 . 显然,除非我直接在测试中调用 ngOnInit
而不是依赖于 fixture.detectChanges()
,否则观察结果将保持冷态 .
我有一个基本的组件类,在ngOnInit里面它订阅了一个服务调用
ngOnInit() {
this.activityService.getActivities().subscribe(activities => {
console.log('inside sub');
this.recentActivities = activities;
});
}
所以我包含了这个console.log来查看这个订阅是否曾经执行过 .
在我的测试中,我spyOn这个活动服务方法返回我需要的数据的Observable集合 . 然后在测试中,我执行整个fixture.detectChanges()处理并期望我的数组长度为1 .
fit('should populate recent activities', () => {
const activities = [new ActivityBuilder()
.withId('1').withRecentActivityActionId(RecentActivityActionType.Created).build()
];
spyOn(activityService, 'getActivities').and.returnValue(of(activities));
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
});
fixture.detectChanges();
expect(component.recentActivities.length).toBe(1);
});
根据Angular文档,他们几乎做了同样的事情,我甚至尝试过fakeAsync方法,但无济于事 . 我在这里想念的是什么?为什么订阅块不执行?
1 回答
经过几个小时的尝试fakeAsync,提供服务的模拟类,各种tick()调用,以及其他几十个帖子和稍微不同的方法,罪魁祸首归结为添加一行:
component.ngOnInit();
.显然,虽然
fixture.detectChanges()
肯定会调用ngOnInit,但它在某种程度上保持了可观察到的冷漠 . 当我打电话给fixture.detectChanges()
时,它不会进入observable的订阅 . 一旦我添加component.ngOnInit()
,observable变得很热,订阅中的代码被执行,我可以看到我的控制台日志被打印 . 奇怪的是,这使得以下fixture.detectChanges()
调用也会跳转到每个后续调用的订阅代码中 .这是我的spec文件的简化版本,希望这可以帮助将来任何人遇到同样的问题 . fakeAsync和同步区域仍然通过测试,我原以为我在fakeAsync区域内至少需要一个tick(),但没有必要 .
});