93

在 Angular 2 中进行测试时,何时使用TestBed中的异步功能?

你什么时候用这个?

 beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MyModule],
            schemas: [NO_ERRORS_SCHEMA],
        });
    });

你什么时候用这个?

beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [MyModule],
        schemas: [NO_ERRORS_SCHEMA],
    });
}));

任何人都可以启发我吗?

4

2 回答 2

104

asyncasync在完成所有任务之前不允许下一个测试开始。所做的是async将回调包装在一个区域中,在该区域setTimeout中跟踪所有异步任务(例如)。一旦所有的异步任务都完成了,那么就async完成了。

如果你曾经在 Angular 之外使用过 Jasmine,你可能已经看到done被传递给回调

it('..', function(done) {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
    done();
  });
});

在这里,这是原生 Jasmine,我们告诉 Jasmine 这个测试应该延迟完成,直到我们调用done(). 如果我们不打电话done()而是这样做:

it('..', function() {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
  });
});

测试甚至会在预期之前完成,因为在测试完成执行同步任务后,promise 就会解决。

使用 Angular(在 Jasmine 环境中),done当我们使用async. 它将跟踪 Zone 中的所有异步任务,当它们全部完成时,done将在后台调用。

在您使用配置的特定情况下TestBed,您通常会在需要时使用它compileComponents。我很少遇到必须以其他方式调用它的情况

beforeEach(async(() => {
   TestBed.configureTestingModule({
     declarations: [MyModule],
     schemas: [NO_ERRORS_SCHEMA],
   })
   .compileComponent().then(() => {
      fixture = TestBed.createComponent(TestComponent);
   });
}));

在测试使用的组件时templateUrl(如果您不使用 webpack),Angular 需要发出 XHR 请求以获取模板,因此组件的编译将是异步的。所以我们应该等到它解决后再继续测试。

于 2016-10-19T09:19:27.973 回答
26

当您在测试中进行异步调用时,实际测试功能在异步调用完成之前完成。当您需要在调用完成时验证某些状态(通常是这种情况)时,测试框架会在异步工作仍在进行时将测试报告为已完成。

通过使用async(...),您可以告诉测试框架等到返回 promise 或 observable 完成后再将测试视为已完成。

it('should show quote after getQuote promise (async)', async(() => {
  fixture.detectChanges();

  fixture.whenStable().then(() => { // wait for async getQuote
    fixture.detectChanges();        // update view with quote
    expect(el.textContent).toBe(testQuote);
  });
}));

传递给的代码then(...)将在测试函数本身完成后执行。async()测试框架意识到,它需要等待 Promise 和 observables 完成,然后才能将测试视为已完成。

也可以看看

于 2016-10-19T09:11:14.433 回答