在angular2测试中,fakeAsync和async有什么区别

时间:2017-03-23 09:09:38

标签: javascript angular jasmine karma-jasmine angular2-testing

我知道tick()函数使用fakeAsync。而且我也可以使用fixture.whenStable()。then()和async以及fakeAsync。我想知道两者的确切用例。任何人都可以用例子解释这个。

注意:我想在两种情况下使用虚假服务或存根。

2 个答案:

答案 0 :(得分:19)

在大多数情况下,它们可以互换使用。除了外部模板和样式未内联编译到组件中以进行测试的组件外,我无法想到任何一个需要的问题。 (即使用SystemJS)。使用SystemJS时,会对外部模板和样式进行XHR调用。在进行XHR调用时,无法使用fakeAsync。另一方面,使用Webpack时,外部模板和样式会内联编译,因此您可以使用fakeAsync

除此之外,我认为这是风格偏好的问题。我可以说的一件事是想象你需要进行多次异步调用,比如this example。你需要嵌套的fixture.whenStable()调用,调用start看起来非常难看

fixture.detectChanges();
fixture.whenStable().then(() => {
  expect(something)

  changeSomething()
  fixture.detectChanges();
  fixture.whenStable().then(() => {
    expect(something)
    changeSomething();
    fixture.detectChanges()

    fixture.whenStable().then(() => {
      expect(somthingeElse)
    })
  })
})

如果没有所有fixture.whenStables()

,这可能看起来更干净(也更容易推理)
fixture.detectChanges();
tick();
expect(something)

changeSomething()
fixture.detectChanges();
tick();
expect(somethingElse)

changeSomething()
fixture.detectChanges();
tick();
expect(somethingElse);

我可能添加的另一件事是我{em> 需要检查fixture.whenStable()中我的来电是否被调用

fixture.whenStable().then(() => {
  expect(...)
  console.log('called...')
})

想象一下,您忘记将测试包裹在async中。没有它,测试将在fixture.whenStable分辨率之前完成,你永远不会知道它。它看起来像测试通过,这是一个误报。实际发生的事情是,断言从未被召唤过。

出于这个原因,我实际上已经离开了async。但是如果你喜欢这种风格,并且相信自己始终将测试包裹在async中,那么请坚持下去。但是对于fakeAsync,所有内容都是同步调用的,因此不能调用断言。

答案 1 :(得分:0)

当我们有 HTTP 调用时使用 async 或 waitForAcync,当没有 HTTP 调用但可观察或 promise 或 setTimeout(不使用 HTTP 调用)时使用 fakeAsync。

基本上带有tick函数的fakeAsync会将时间提前指定的毫秒数,因此tick(50000)会执行任何会在50秒内发生的异步任务,一眼就能完成。因为它使时间提前了 50 秒。请看下面的示例,因为 setTimeout 在 async 或 waitForAcync 的情况下需要 50 秒才能执行,但 fakeAsynch 不会花费时间。

describe('this test', () => {
  it('looks async but is synchronous', fakeAsync(() => {
       let flag = false;
       setTimeout(() => {
         flag = true;
       }, 50000);
       expect(flag).toBe(false);
       tick(25000);
       expect(flag).toBe(false);
       tick(25000);
       expect(flag).toBe(true);
     }));
});