使用FakeAsync对Angular异步代码进行单元测试
The problem with async is that we still have to introduce real waiting in our tests, and this can make our tests very slow.
Async的一個缺陷是,我們仍然需要在測試代碼中引入真實的等待,這會拖慢我們的單元測試速度。
fakeAsync comes to the rescue and helps to test asynchronous code in a synchronous way.
FakeAsync可以允許我們以同步的方式去測試異步代碼。
一個例子:
<h1>{{ incrementDecrement.value }} </h1><button (click)="increment()" class="increment">Increment </button>increment方法的實現:
increment() {this.incrementDecrement.increment(); }incrementDecrement service的實現:
increment() {setTimeout(() => {if (this.value < 15) {this.value += 1;this.message = '';} else {this.message = 'Maximum reached!';}}, 5000); // wait 5 seconds to increment the value }測試代碼:
import { TestBed, fakeAsync, tick, ComponentFixture } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { DebugElement } from '@angular/core';import { AppComponent } from './app.component'; import { IncrementDecrementService } from './increment-decrement.service'; describe('AppComponent', () => {let fixture: ComponentFixture<AppComponent>;let debugElement: DebugElement;beforeEach(async(() => {TestBed.configureTestingModule({declarations: [AppComponent],providers: [IncrementDecrementService]}).compileComponents();fixture = TestBed.createComponent(AppComponent);debugElement = fixture.debugElement; }) );it('should increment in template after 5 seconds', fakeAsync(() => {debugElement.query(By.css('button.increment')).triggerEventHandler('click', null);tick(2000);fixture.detectChanges();let value = debugElement.query(By.css('h1')).nativeElement.innerText;expect(value).toEqual('0'); // value should still be 0 after 2 secondstick(3000);fixture.detectChanges();const value = debugElement.query(By.css('h1')).nativeElement.innerText;expect(value).toEqual('1'); // 3 seconds later, our value should now be 1 }));FakeAsync block內的tick代碼,能在特定的zone里,模擬時間的流逝。Tick參數的單位是毫秒。
Tick can also be used with no argument, in which case it waits until all the microtasks are done (when promises are resolved for example).
如果不帶參數,則直至所有的microtasks都結束,即promises都resolved之后再返回。
也可以選用flush方法:It basically simulates the passage of time until the macrotask queue is empty. Macrotasks include things like setTimouts, setIntervals and requestAnimationFrame.
直至所有的microtasks都結束,包括setTimeouts,setIntervals和requestAnimationFrame結束,flush才返回。
使用flush改寫的例子:
it('should increment in template', fakeAsync(() => {debugElement.query(By.css('button.increment')).triggerEventHandler('click', null);flush();fixture.detectChanges();const value = debugElement.query(By.css('h1')).nativeElement.innerText;expect(value).toEqual('1'); }));總結
以上是生活随笔為你收集整理的使用FakeAsync对Angular异步代码进行单元测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Async对Angular异步代码进
- 下一篇: 华为p30夜景怎么拍