【发布时间】:2021-02-12 00:37:03
【问题描述】:
我最近写了很多异步单元测试,结合使用 Angular 的 fakeAsync,从 async 测试体函数返回 Promises,Jasmine done 回调等。一般我已经能够让一切都以完全确定的方式工作。
我的代码的一些部分与非常复杂且难以模拟的第 3 方库以非常复杂的方式交互。我想不出一种方法来挂钩事件或生成保证在该库完成后台工作后解决的 Promise,所以目前我的测试使用setTimeout 卡住了:
class MyService {
public async init() {
// Assume library interaction is a lot more complicated to replace with a mock than this would be
this.libraryObject.onError.addEventListener(err => {
this.bannerService.open("Load failed!" + err);
});
// Makes some network calls, etc, that I have no control over
this.libraryObject.loadData();
}
}
it("shows a banner on network error", async done => {
setupLibraryForFailure();
await instance.init();
setTimeout(() => {
expect(banner.open).toHaveBeenCalled();
done();
}, 500); // 500ms is generally enough... on my machine, probably
});
这让我很紧张,尤其是setTimeout 中的神奇数字。它的扩展性也很差,因为我确信 500 毫秒比我完成任何其他测试所需的时间要长得多。
我想我想做的是能够告诉 Jasmine 轮询 banner.open 间谍,直到它被调用,或者直到测试超时结束并且测试失败。然后,一旦错误处理程序被触发并完成,测试就应该注意到。有没有更好的方法,或者这是一个好主意?它是我没有看到的某个地方的内置模式吗?
【问题讨论】:
标签: javascript unit-testing asynchronous jasmine