测试异步操作

有时候,我们需要测试依赖于在特定时间发生的异步操作的组件。 Angular提供了一个称为fakeAsync的函数,它将我们的测试包裹在一个区域中,并让我们访问tick函数,这将允许我们精确地模拟时间的流逝。

让我们回到QuoteComponent组件的例子,并使用fakeAsync重写单元测试:

  1. import { Component } from '@angular/core';
  2. import { QuoteService } from './quote.service';
  3. @Component({
  4. selector: 'my-quote',
  5. template: '<h3>Random Quote</h3> <div>{{quote}}</div>'
  6. })
  7. export class QuoteComponent {
  8. quote: string;
  9. constructor(private quoteService: QuoteService){};
  10. getQuote() {
  11. this.quoteService.getQuote().then((quote) => {
  12. this.quote = quote;
  13. });
  14. };
  15. }
  1. import { QuoteService } from './quote.service';
  2. import { QuoteComponent } from './quote.component';
  3. import { provide } from '@angular/core';
  4. import {
  5. async,
  6. TestBed,
  7. fakeAsync,
  8. tick,
  9. } from '@angular/core/testing';
  10. class MockQuoteService {
  11. public quote: string = 'Test quote';
  12. getQuote() {
  13. return Promise.resolve(this.quote);
  14. }
  15. }
  16. describe('Testing Quote Component', () => {
  17. let fixture;
  18. beforeEach(() => {
  19. TestBed.configureTestingModule({
  20. declarations: [
  21. QuoteComponent
  22. ],
  23. providers: [
  24. { provide: QuoteService, useClass: MockQuoteService }
  25. ]
  26. });
  27. fixture = TestBed.createComponent(QuoteComponent);
  28. fixture.detectChanges();
  29. });
  30. it('Should get quote', fakeAsync(() => {
  31. fixture.componentInstance.getQuote();
  32. tick();
  33. fixture.detectChanges();
  34. const compiled = fixture.debugElement.nativeElement;
  35. expect(compiled.querySelector('div').innerText).toEqual('Test quote');
  36. }));
  37. });

View Example

这里我们有一个QuoteComponent,它有一个getQuote触发异步更新。 我们将整个测试包装在fakeAsync中,这将允许我们通过调用tick()来使用同步函数调用来测试我们的组件(getQuote())的异步行为。 然后我们可以运行detectChanges并查询DOM的预期结果。