使用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 seconds
tick(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');
}));
相關文章
- 如果利用 python 對 java 程式碼進行 單元測試?PythonJava
- 使用Angular CLI進行單元測試和E2E測試Angular
- 使用CountDownLatch或迴圈屏障對多執行緒程式碼進行單元測試 -XebiaCountDownLatch執行緒
- 使用JUnit進行單元測試
- 使用jest進行單元測試
- [譯]對 React 元件進行單元測試React元件
- 使用Jest進行React單元測試React
- 如何使用MOQ進行單元測試
- 使用 Spring Boot 進行單元測試Spring Boot
- Angular如何對包含了HTTP請求的服務類進行單元測試AngularHTTP
- 使用springboot對各層的程式碼進行測試!Spring Boot
- 程式碼重構與單元測試——對方法的引數進行重構(五)
- Python中的單元測試框架:使用unittest進行有效測試Python框架
- 如何對Spring MVC中的Controller進行單元測試SpringMVCController
- 使用python對oracle進行簡單效能測試PythonOracle
- 單元測試效率優化:為什麼要對程式進行測試?測試有什麼好處?優化
- Jest & enzyme 進行react單元測試React
- Angular單元測試如何只執行指定的測試用例,提高測試速度Angular
- Angular8單元測試示例指南Angular
- 使用gtest進行自己的單獨測試的程式碼介紹
- 對圖資料庫(Nebula)進行單元測試時的坑資料庫
- 在C#中進行單元測試C#
- 如何進行裝置的非對稱效能測試
- 程式碼重構與單元測試——使用“以查詢取代臨時變數”再次對Statement()方法進行重構(七)變數
- 使用SAP CRM mock框架進行單元測試的設計Mock框架
- JavaScript 測試教程-part 1:用 Jest 進行單元測試JavaScript
- 程式碼重構與單元測試——重構1的單元測試(四)
- 如何對第一個Vue.js元件進行單元測試 (上)Vue.js元件
- 如何對第一個Vue.js元件進行單元測試 (下)Vue.js元件
- 使用karma和jasmine配合phantom瀏覽器進行單元測試ASM瀏覽器
- 程式碼重構與單元測試(一)
- 程式碼重構與單元測試——測試專案(二)
- 如何編寫優秀的測試程式碼|單元測試
- FastAPI(43)- 基於 pytest + requests 進行單元測試ASTAPI
- unittest 單元測試框架教程 1-執行測試指令碼框架指令碼
- James Shore:不要使用單元測試的程式碼覆蓋率
- 程式碼重構與單元測試——繼續將相應的方法進行移動(八)
- 使用 PyHamcrest 執行健壯的單元測試REST