describe('ReactiveFormsAutoCompleteSearchingComponent', () => { let component: ReactiveFormsAutoCompleteSearchingComponent; let fixture: ComponentFixture<ReactiveFormsAutoCompleteSearchingComponent>;
describe('Property searchingInputControl', () => { it('should be a instance of FormControl', () => { // Assert expect(component.searchingInputControl).toBeInstanceOf(FormControl); }); });
describe('Property stations$', () => { it('should be a instance of FormControl', () => { // Assert expect(component.stations$).toBeInstanceOf(Observable); });
describe('when it be subscribed', () => { let service: ReactiveFormsAutoCompleteSearchingService; beforeEach(() => { service = TestBed.inject(ReactiveFormsAutoCompleteSearchingService); spyOn(service, 'searchStation').and.returnValue(of([])); });
it('should call function "searchStation" of the service with empty string', (done) => { // Act component.stations$.subscribe(() => { // Assert expect(service.searchStation).toHaveBeenCalledOnceWith(''); done(); }); });
describe('when the input value changes', () => { it('should call function "searchStation" of the service with the value', (done) => { // Arrange const value = 'Leo' // Act component.stations$.subscribe(() => { // Assert expect(service.searchStation).toHaveBeenCalledOnceWith(value); done(); }); component.searchingInputControl.patchValue(value); }); });
describe('when the input value changes twice quickly', () => { it('should call function "searchStation" of the service once with the last value', (done) => { // Arrange const firstValue = 'Leo' const secondValue = 'Chen' // Act component.stations$.subscribe(() => { // Assert expect(service.searchStation).toHaveBeenCalledOnceWith(secondValue); done(); }); component.searchingInputControl.patchValue(firstValue); component.searchingInputControl.patchValue(secondValue); }); });
describe('when the input value changes twice slowly', () => { it('should call function "searchStation" of the service twice', fakeAsync(() => { // Arrange const firstValue = 'Leo' const secondValue = 'Chen' // Act component.stations$.subscribe(); component.searchingInputControl.patchValue(firstValue); tick(600); component.searchingInputControl.patchValue(secondValue); tick(600); // Assert expect(service.searchStation).toHaveBeenCalledTimes(2); expect(service.searchStation).toHaveBeenCalledWith(firstValue); expect(service.searchStation).toHaveBeenCalledWith(secondValue); })); }); }) });
測試結果:
在上述的測試程式碼中,我們可以看到今天要分享給大家的最後一個技巧:非同步測試。
Angular 的非同步測試技巧
在驗證非同步事件處理邏輯如 Promise 與 Observable 時,最簡單的方式當然就是直接 then 或是 subscribe 之後再驗證。
而這時我們會在傳入 it 的函式裡,多一個名為 done 的參數 (你要取名為別的名字也可以) ,如此我們就可以讓測試知道我們要等非同步事件完成後再行驗證。