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

San*_*nju 5 unit-testing typescript karma-jasmine angular

我正在试图弄清楚fakeAsync的tick()方法与堆栈溢出的done()一些答案所建议的区别.

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

为什么angular认为它比使用或更可行的方法asyncfakeAsync

举个例子.

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

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);
});
Run Code Online (Sandbox Code Playgroud)

但是以下方法返回' 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);
}));
Run Code Online (Sandbox Code Playgroud)

注意:

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

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

max*_*992 13

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

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

您也可以使用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
  })
);
Run Code Online (Sandbox Code Playgroud)

现在,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
  })
);
Run Code Online (Sandbox Code Playgroud)

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

  • 您还可以添加“done”是本机 Jasmine 方法,而“async”和“fakeAsync”是由 Angular 测试框架添加的 (4认同)
  • 这个故事中哪里提到了tick()? (4认同)
  • Tick与flush几乎相同。Flush 将运行队列中的所有异步任务,如果未提供参数,tick 也会运行。但您也可以决定以毫秒为单位传递一个时间,它将运行只应该在该时间内运行的任务。例如,如果您必须设置超时,一个设置为 2 秒,另一个设置为 1 秒,则运行 tick(1000) 并且只会调用第一个回调。 (4认同)