[英]Test cases passes when run by itself but fails when run in a group
我有以下幾個測試用例,它們在單獨執行時可以成功運行,但是在分組運行時會隨機失敗。 他們都使用setTimeout
。 他們是在一個spec
的單獨隔離的文件describe
的方法。
例如。 當我自己運行它時,該測試用例(使用setTimeout
)通過,但是當我在一個組中運行它時,它失敗了。 我懷疑問題與setTimeout
。 我嘗試使用done
但不能解決問題。
describe('AppComponent Test suite', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AppComponent,
...
],
imports: [
....
],
providers: [{provide: APP_BASE_HREF, useValue: '/'},
....]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
let componentDE = fixture.debugElement;
let componentNE:HTMLElement = componentDE.nativeElement;
componentNE.setAttribute("signup","someIncorrectValue");
fixture.detectChanges();
});
it('should show dialog message if the application has unrecognised value of signup attribute in url',(done)=>{
spyOn(component,'showDialog');
setTimeout(()=>{
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
},1000); done();
});
});
想象在同一個文件中有更多類似的測試用例,每個用自己的describe
,全部使用setTimeout
。
他們為什么失敗? 如果問題是同步,我該如何同步它們?
更新
我也嘗試了async
/ await
,但沒有喜悅!
it('should show dialog message if the application has unrecognised value of signup attribute in url',async ()=>{
spyOn(component,'showDialog');
await setTimeout(()=>{
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
},1000);
});
我也將調用移到setTimeout
的回調內done
但那里也沒有樂趣。
it('should show dialog message if the application has unrecognised value of signup attribute in url', (done)=>{
spyOn(component,'showDialog');
setTimeout(()=>{
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
done();
},1000);
});
該組件是應用程序的入口點,並通過在url
傳遞一個signup
屬性來調用。
<app-root signup=@signup>
注冊會在啟動時告知Angle,因為用戶單擊了注冊鏈接,該應用是否已啟動。 因此,角度可以顯示注冊成功與否的消息。 早些時候,我遇到以下問題( 從另一個組件更新一個組件的屬性時出現ExpressionChangedAfterItHasBeenCheckedError錯誤 )並解決該問題,我在應用程序組件的ngAfterViewInit
中添加了setTimeout
ngAfterViewInit(){
setTimeout(()=>{
this.checkIfSignupProcess();
this.authGuard.authGuardError$.subscribe((authGuardContext:AuthGuardContext)=>{
this.handleAuthGuardContextMessage(authGuardContext);
});
this.dialogService.dialogMessage$.subscribe((message:DialogServiceMessageContext)=>{
console.log("received message from Dialog box service");
this.handleDialogServiceMessage(message);
})
},100);
/*
OR
this.isSignupProcess(); //this will cause ExpressionChangedAfterItHasBeenCheckedError error s the function changes message of DialogComponent but the change detection isn't complete.
this.cd.detectChanges();
*/
}
更新2
我嘗試使用“ tick”,但即使單獨運行,測試仍然失敗。
fit('should show dialog message if the application has unrecognised value of signup attribute in url', ()=>{
jasmine.clock().install();
spyOn(component,'showDialog');
setTimeout(() => {
console.log("in spec's timeout");
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
},1000);
jasmine.clock().tick(1001);
jasmine.clock().uninstall();
/*setTimeout(()=>{
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
done();
},1000);*/
});
失敗的原因是Expected spy showDialog to have been called with [ 'Unrecognised message: someIncorrectValue', Function ] but it was never called.
更新3
我注意到,即使超時值在我的組件中為100,在我的規格中為1000,規格超時也首先過期!
即使組件中的超時值為100,而組件中的超時值為10000,我的組件中應顯示對話框的此代碼也會在我的規范代碼之后被調用!
組件的超時
setTimeout(()=>{
console.log("timeout of component");
this.checkIfSignupProcess();
...,100
}
規范的超時
fit('should show dialog message if the application has unrecognised value of signup attribute in url', ()=>{
jasmine.clock().install();
spyOn(component,'showDialog');
setTimeout(() => {
console.log("in spec's timeout 10000");
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
},10000);
jasmine.clock().tick(10001);
jasmine.clock().uninstall();
/*setTimeout(()=>{
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
done();
},1000);*/
});
不知道為什么它們會失敗,但是為了擺脫setTimeout
,您可以嘗試將callThrough
和callFake
組合如下:
it('should show dialog ...', (done)=>{
spyOn(component,'showDialog').and.callThrough().and.callFake(() => {
expect(component.showDialog).toHaveBeenCalledWith("Unrecognised message: someIncorrectValue",jasmine.any);
done();
});
});
最后,我將測試用例重新組織為以下內容(從規范中刪除了setTimeout
,並直接從規范中調用了被測函數。
it('should show dialog message if the application has got error signup attribute in url', ()=>{
spyOn(component,'showDialog')
component.checkIfSignupProcess();
expect(component.showDialog).toHaveBeenCalledWith("Error: Signup wasn't successful",new DialogContext(''));
})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.