我写了一个非常简单的测试,期望组件是真实的。它正在工作,但是一旦我把SetTimeOut放在oninit上它就开始失败了。
错误:超时 - 超时内未调用异步回调 由jasmine.DEFAULT_TIMEOUT_INTERVAL指定。
describe('AppComponent', () => {
let appComponent: AppComponent;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
var errorMessages = new Array<ErrorMessage>();
errorMessages.push(new ErrorMessage(500));
TestBed.configureTestingModule({
declarations: [
AppComponent
],
imports: [
RouterTestingModule,
MessagesModule
],
providers: [
{ provide: AuthService, useValue: TestHelper.createAuthServiceSpy() },
{ provide: ErrorHandlingService, useValue: TestHelper.createErrorHandlingServiceSpy(errorMessages) }
]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
appComponent = fixture.debugElement.componentInstance;
fixture.detectChanges();
}));
it('should create the app', async(() => {
expect(appComponent).toBeTruthy();
}));
it('should show error in case of failure', async(() => {
expect(appComponent.errorMessage.length).toBe(1);
}));
it('should get username for loggedin user', async(() => {
expect(appComponent.username).toBe("username");
}));
});
所有3个都失败了,当我评论SetTimeOut时,它开始传递。
export class AppComponent implements OnInit {
username: string = "";
errorMessage: Message[] = [];
showError: boolean = false;
private activatedRoute: ActivatedRoute;
constructor(public authService: AuthService, private renderer: Renderer, private errorhandlingService: ErrorHandlingService, private router: Router, private titleService: Title) {
localStorage.removeItem(AppConstants.authenticationLocalStorageKey);
}
ngOnInit(): void {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
var title = this.getTitle(this.router.routerState, this.router.routerState.root).join('-');
this.titleService.setTitle(title);
}
});
this.errorhandlingService.getErrors().subscribe(errorMessages => {
let errorMessage: ErrorMessage = errorMessages.pop();
this.errorMessage = errorMessage ? [{ severity: 'error', summary: `Error Code: ${errorMessage.statusCode}`, detail: `(${errorMessage.text})` }] : [];
this.renderer.setElementProperty(document.body, "scrollTop", 0);
this.showError = true;
setTimeout(() => {
this.showError = false;
}, AppConstants.errorMessageFadeTime);
});
this.authService.getUsername().subscribe(data => this.username = data
, error => this.errorhandlingService.handleError(error, 'could not get username'));
}
onDeactivate() {
//scroll to top of page after routing
this.renderer.setElementProperty(document.body, "scrollTop", 0);
}
private getTitle(state, parent) {
var data = [];
if (parent && parent.snapshot.data && parent.snapshot.data.title) {
data.push(parent.snapshot.data.title);
}
if (state && parent) {
data.push(... this.getTitle(state, state.firstChild(parent)));
}
return data;
}
}
下面是html
<div>
<div class="center-text">
<div class="errorMessage" *ngIf="showError"><p-messages [value]="errorMessage"></p-messages></div>
<router-outlet (deactivate)="onDeactivate()"></router-outlet>
</div>
</div>
我尝试过fakesync并完成但仍然得到同样的错误,有什么建议吗?
答案 0 :(得分:0)
我建议你创建一个假类,如下所示
let errorOccured = false;
class FakeAuthService {
getErrors(){
return Observable.of(errorOccured);
}
}
providers: [
{ provide: AuthService, useClass: FakeAuthService},
]
通过
将其注入TestBed
beforeEach
authService = TestBed.get(AuthService);
在beforeEach async
let authService : AuthService
更新1:
将订阅的完成事件中的setTimeOut
逻辑设为
this.errorhandlingService.getErrors().subscribe(errorMessages => {
let errorMessage: ErrorMessage = errorMessages.pop();
this.errorMessage = errorMessage ? [{ severity: 'error', summary: `Error Code: ${errorMessage.statusCode}`, detail: `(${errorMessage.text})` }] : [];
this.renderer.setElementProperty(document.body, "scrollTop", 0);
this.showError = true;
},error=>{},
()=>{
setTimeout(() => {
this.showError = false;
}, AppConstants.errorMessageFadeTime);
});
答案 1 :(得分:0)
假设第二部分代码在您的实际服务中,而不是测试:
Angular提供的async
回调查看并等待Observables
,Promises
和setTimeouts
等异步代码。它会在检查答案之前尝试解析被测试组件的方法调用。
Jasmine本身有一个名为DEFAULT_TIMEOUT_INTERVAL
的配置选项。在异步测试中(仅使用jasmine,而不是Angular的测试工具),您可以将名为done()
的方法传递到it
块中,并且Jasmine将等待一定的时间间隔来调用该方法。这是为了测试异步测试。默认超时为5秒,因此如果您正在调用超时5000,那么由于setTimeout执行shenanigans,这可能不足以让Jasmine检查。
Angular的async
将Jasmine done()
包装成一个很好的小调用,在异步函数完成后执行测试。
无论哪种方式,您只想在是异步的测试中使用async
。如果测试没有异步结果,请不要让测试等待。
在您的情况下,您可以为异步测试设置beforeEach
块,并将您的assert
包装在超过5000的超时中,或者您可以仅为这些测试更改jasmine配置:
... previous tests
describe('timeout tests', () => {
beforeEach(() => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5250;
});
it('should display error for five seconds', async(() => {
...tests
}));
});
... more tests