在angular2测试中,fakeAsync的tick()和done()有什么区别?

时间:2017-10-20 06:48:09

标签: angular unit-testing typescript karma-jasmine

我正在尝试弄清楚某些answers在堆栈溢出时建议将fakeAsync的tick()方法与done()区分开来。

使用tick()我们可以模拟超时,但是我们可以使用done()完成相同的操作吗?

为什么angular将其视为more viable method而不是使用asyncfakeAsync

以p为例。

这种方法对我有用......

it("Should display names",(done:any) => {
        component.names = [
            {
                "firstname": "abc",
                "lastname": "max"
            },
            {
                "firstname": "def",
                "lastname": "max"
            },
        ];
        done();
        fixture.detectChanges();
        let wrapBox = fixture.debugElement.queryAll(By.css('.wrapBox'));
        console.log(wrapBox);
});

但是以下方法会返回' 6 timer(s) still in queue '错误...

it("Should display names",fakeAsync(() => {
        component.names = [
            {
                "firstname": "abc",
                "lastname": "max"
            },
            {
                "firstname": "def",
                "lastname": "max"
            },
        ];
        tick();
        fixture.detectChanges();
        let wrapBox = fixture.debugElement.queryAll(By.css('.wrapBox'));
        console.log(wrapBox);
}));

注意

  1. 数组 names 的数据是异步的,因为它是使用'get'操作从后端检索的。但是我在这里嘲笑数据。

  2. 数组中的数据被迭代并传递给另一个子组件,该子组件在视图中显示它。

2 个答案:

答案 0 :(得分:11)

这两件事没有任何共同之处。

done只是一个让你的测试运行器知道异步操作何时完成的回调。

例如:

it('should wait for this promise to finish', done => {
  const p = new Promise((resolve, reject) =>
    setTimeout(() => resolve(`I'm the promise result`), 1000)
  );

  p.then(result => {
    // following will display "I'm the promise result" after 1s
    console.log(result);

    // this let your test runner know that it can move forward
    // because we're done here
    // the test will take 1s due to the setTimeout at 1000ms
    done();
  });
});

您也可以使用async(只是为了避免手动调用done):

it(
  'should wait for this promise to finish',
  async(() => {
    const p = new Promise((resolve, reject) =>
      setTimeout(() => resolve(`I'm the promise result`), 1000)
    );

    p.then(result =>
      // following will display "I'm the promise result" after 1s
      console.log(result)
    );

    // notice that we didn't call `done` here thanks to async
    // which created a special zone from zone.js
    // this test is now aware of pending async operation and will wait
    // for it before passing to the next one
  })
);

现在,fakeAsync可让您随着时间的推移控制(这非常强大),因此您可以以同步方式编写测试,并模拟该时间过去以避免等待setTimeout例如:

it(
  'should wait for this promise to finish',
  fakeAsync(() => {
    const p = new Promise((resolve, reject) =>
      setTimeout(() => resolve(`I'm the promise result`), 1000)
    );

    // simulates time moving forward and executing async tasks
    flush();

    p.then(result =>
      // following will display "I'm the promise result" **instantly**
      console.log(result)
    );

    // notice that we didn't call `done` here has there's no async task pending
  })
);

所以,要清楚一点,在最后一个例子中使用fakeAsync,如果setTimeout设置为10s,测试仍然会立即执行

答案 1 :(得分:0)

我做了一个小测试,可以帮助我了解刻度线可以做什么:

px