使用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');
}));
相關文章
- 如何對非同步呼叫進行單元測試非同步
- 使用Angular CLI進行單元測試和E2E測試Angular
- 如果利用 python 對 java 程式碼進行 單元測試?PythonJava
- 用 Mocha 和 Chai 對 JavaScript 程式碼進行單元測試AIJavaScript
- 使用JUnit進行單元測試
- 使用CountDownLatch或迴圈屏障對多執行緒程式碼進行單元測試 -XebiaCountDownLatch執行緒
- [譯]對 React 元件進行單元測試React元件
- 使用Jest進行React單元測試React
- 使用 Spring 進行單元測試Spring
- 使用 QUnit 進行 JavaScript 單元測試JavaScript
- Angular如何對包含了HTTP請求的服務類進行單元測試AngularHTTP
- 安卓單元測試 (十一):非同步程式碼怎麼測試安卓非同步
- 使用xUnit為.net core程式進行單元測試(4)
- 使用xUnit為.net core程式進行單元測試(3)
- 使用xUnit為.net core程式進行單元測試 -- Assert
- 使用xUnit為.net core程式進行單元測試(1)
- 使用 Spring Boot 進行單元測試Spring Boot
- 程式碼重構與單元測試——對方法的引數進行重構(五)
- 在Hadoop中使用MRUnit進行單元測試Hadoop
- 單元測試效率優化:為什麼要對程式進行測試?測試有什麼好處?優化
- Python中的單元測試框架:使用unittest進行有效測試Python框架
- Jest & enzyme 進行react單元測試React
- Angular單元測試如何只執行指定的測試用例,提高測試速度Angular
- 使用springboot對各層的程式碼進行測試!Spring Boot
- 使用 Feed4JUnit 進行資料與程式碼分離的 Java 單元測試Java
- Angular8單元測試示例指南Angular
- 使用python對oracle進行簡單效能測試PythonOracle
- 利用HSQLDB 進行Hibernate單元測試SQL
- 在C#中進行單元測試C#
- 對圖資料庫(Nebula)進行單元測試時的坑資料庫
- JavaScript 測試教程-part 1:用 Jest 進行單元測試JavaScript
- 使用SAP CRM mock框架進行單元測試的設計Mock框架
- 使用gtest進行自己的單獨測試的程式碼介紹
- 程式碼重構與單元測試——重構1的單元測試(四)
- symfony2 用phpunit進行單元測試PHP
- 如何對第一個Vue.js元件進行單元測試 (上)Vue.js元件
- 如何對第一個Vue.js元件進行單元測試 (下)Vue.js元件
- 如何對Spring MVC中的Controller進行單元測試SpringMVCController