我最近写了很多异步单元测试,结合了Angular的
fakeAsync
,从返回Promises
async
测试身体功能,茉莉花
done
回调等。一般来说,我能够以一种完全确定的方式使一切正常工作。
我的代码的一些部分与第三方库的交互方式非常复杂,很难模仿。我无法找到一种方法来挂接一个事件或生成一个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毫秒比我完成的任何其他测试都要长得多。
我想我想做的是,能够告诉贾斯敏去投票
banner.open
间谍,直到它被调用,或者直到测试超时并且测试失败。然后,一旦错误处理程序被触发并完成,测试就会注意到。是否有更好的方法,或者这是一个好主意?这是我没有看到的某个内置模式吗?