繁体   English   中英

期望茉莉花间谍在超时之前被称为“最终”

[英]Expect jasmine Spy to be called "eventually", before timeout

我最近写了很多异步单元测试,使用了 Angular 的fakeAsync的组合,从async测试主体函数返回 Promises,Jasmine done回调等。通常我已经能够让一切以完全确定的方式工作。

我的代码的一些部分与非常复杂且难以模拟的 3rd 方库以深度纠缠的方式交互。 我想不出一种方法来挂钩事件或生成保证在此库完成后台工作后解决的 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间谍,直到它被调用,或者直到测试超时和测试失败。 然后,一旦错误处理程序被触发并完成,测试就会注意到。 有没有更好的方法,或者这是一个好主意? 它是我没有看到的某个地方的内置模式吗?

我认为您可以利用callFake ,基本上是在调用此函数后调用另一个函数。

像这样的东西:

it("shows a banner on network error", async done => {
    setupLibraryForFailure();
    // maybe you have already spied on banner open so you have to assign the previous
    // spy to a variable and use that variable for the callFake
    spyOn(banner, 'open').and.callFake((arg: string) => {
      expect(banner.open).toHaveBeenCalled(); // maybe not needed because we are already doing callFake
      done(); // call done to let Jasmine know you're done
    });
    await instance.init();
});

我们在 banner.open 上设置了一个间谍,当它被调用时,它将使用 callFake 调用回调函数,我们在这个回调中调用 done 让 Jasmine 知道我们已经完成了我们的断言。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM