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

xio*_*tee 74 unit-testing karma-jasmine angular2-testing angular angular-test

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

你什么时候用的?

 beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MyModule],
            schemas: [NO_ERRORS_SCHEMA],
        });
    });
Run Code Online (Sandbox Code Playgroud)

你何时使用它?

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

任何人都可以启发我吗?

Pau*_*tha 83

asyncasync完成所有任务之前,将不允许下一个测试开始.什么async是在区域中包装回调,其中setTimeout跟踪所有异步任务(例如).完成所有异步任务后,即async完成.

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

it('..', function(done) {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
    done();
  });
});
Run Code Online (Sandbox Code Playgroud)

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

it('..', function() {
  someAsyncAction().then(() => {
    expect(something).toBe(something);
  });
});
Run Code Online (Sandbox Code Playgroud)

测试将在期望之前完成,因为在测试完成执行同步任务,promise将解析.

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

在您的TestBed配置的特定情况下,您通常会在需要时使用它compileComponents.我很少遇到一种我不得不称之为的情况

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

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

  • @vincecampanale templateUrl仅在beforeEach中的配置过程中起作用。在这种情况下,您需要调用`compileComponents`。如果您要查询的话,则与在每个测试中使用`async`无关。为了安全起见(应何时调用`compileComponents`),请参见[我应该何时调用compileComponents](/sf/ask/3052587891/) (2认同)
  • @vincecampanale并非总是希望将其称为_before_测试。有时您可能需要在进行一些初始化后调用它。您需要了解调用它的实际作用。大多数情况下,它应该可以。但是我个人不喜欢他们自己做这个决定。但是我看到很多人碰到这个问题,他们忘记了称呼它,他们想知道为什么有些东西行不通。因此,最好是由他们来生成电话。该位置可能值得商bat,但至少他们称之为 (2认同)
  • @vincecampanale通常,当您想要(重新)渲染视图时,应该调用它。例如,创建组件->渲染视图。但是,如果要首先初始化某些内容,例如创建组件->更改用于渲染的组件中的值->渲染视图。这就是我的意思,也许您想先初始化一些东西 (2认同)

Gün*_*uer 23

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

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

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

也可以看看