测试异步操作

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Component } from '@angular/core';
import { QuoteService } from './quote.service';

@Component({
selector: 'my-quote',
template: '<h3>Random Quote</h3> <div>{{quote}}</div>'
})

export class QuoteComponent {
quote: string;

constructor(private quoteService: QuoteService){};

getQuote() {
this.quoteService.getQuote().then((quote) => {
this.quote = quote;
});
};
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { QuoteService } from './quote.service';
import { QuoteComponent } from './quote.component';
import { provide } from '@angular/core';
import {
async,
TestBed,
fakeAsync,
tick,
} from '@angular/core/testing';

class MockQuoteService {
public quote: string = 'Test quote';

getQuote() {
return Promise.resolve(this.quote);
}
}

describe('Testing Quote Component', () => {

let fixture;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
QuoteComponent
],
providers: [
{ provide: QuoteService, useClass: MockQuoteService }
]
});
fixture = TestBed.createComponent(QuoteComponent);
fixture.detectChanges();
});

it('Should get quote', fakeAsync(() => {
fixture.componentInstance.getQuote();
tick();
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('div').innerText).toEqual('Test quote');
}));
});

View Example

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