Angular 2测试-异步函数调用-何时使用


86

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

什么时候使用这个?

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

你什么时候使用这个?

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

有人可以启发我吗?

Answers:


95

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);
  });
});

该测试甚至可以在期望之前完成,因为承诺测试完成执行同步任务之后就解决了。

使用Angular(在Jasmine环境中),done当我们使用时,Angular实际上会在幕后调用async。它将跟踪区域中的所有异步任务,并在完成所有异步任务后在done后台调用它们。

对于特定的TestBed配置情况,您通常会在需要时使用它compileComponents。我很少遇到不得不以其他方式称呼它的情况

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

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


很好的答案@peeskillet。只是为了确保我理解它:如果您有内联模板,async则没有必要。当您使用时templateUrl,它是。但是,包括async将不会“破坏”内联模板组件。您是否可以肯定地说async每个测试都可以默认使用?

2
@vincecampanale templateUrl仅在beforeEach中的配置期间起作用。在这种情况下,您需要致电compileComponents。这是否与async您要使用的测试无关。为了安全起见(应在何时调用compileComponents),请参阅我何时应调用compileComponents
Paul Samsotha

2
@vincecampanale并非总是希望在测试之前调用它。有时您可能需要在进行一些初始化后调用它。您需要了解调用它的实际作用。大多数情况下,它应该可以。但是我个人不喜欢他们自己做这个决定。但是我看到很多人遇到了问题,他们忘了称呼它,他们想知道为什么有些东西行不通。因此,最好是由他们来生成呼叫。该位置可能值得商
bat

2
@vincecampanale通常,当您想要(重新)渲染视图时,应该调用它。例如,创建组件->渲染视图。但是,如果您想首先初始化诸如创建组件->更改用于渲染的组件中的值->渲染视图。这就是我的意思,也许您想先初始化一些东西
Paul Samsotha

1
还有件事儿。第一次调用它是ngOnInit在组件中调用的时间。有时在测试时很重要
Paul Samsotha

26

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

使用,async(...)您可以告诉测试框架等待返回的诺言或可观察的结果完成,然后再将测试视为已完成。

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()

也可以看看

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.