Angular 2+,异步测试和 setTimeout
Posted
技术标签:
【中文标题】Angular 2+,异步测试和 setTimeout【英文标题】:Angular 2+, async testing and setTimeout 【发布时间】:2018-12-03 07:50:20 【问题描述】:我有一个关于测试的问题。 我使用 Angular 6、karma 和 jasmine。
我的测试是:
it(`my test`, async(() =>
console.log('### start test');
fixture.detectChanges();
// call a method which has async code
fixture.componentInstance.fakeTimeout();
console.log('isStable', fixture.isStable());
fixture.whenStable().then(() =>
// here I must check smth only when all async operations are completed
console.log('### end test');
);
));
我尝试以不同的方式实现fakeTimeout
方法,即:
public fakeTimeout()
new Promise((resolve, reject) =>
setTimeout(() =>
console.log('>>>>>> COMPONENT TIMEOUT!!!');
resolve(true);
, 2000);
).then(() => );
或
public fakeTimeout()
setTimeout(() =>
console.log('>>>>>> COMPONENT TIMEOUT!!!');
, 2000);
在这两种情况下,我都有以下日志:
### start test
isStable true
### end test
>>>>>> COMPONENT TIMEOUT!!!
但是,根据官方文档,whenStable
promise 只有在所有异步操作完成后才会解析,并且日志必须是:
### start test
isStable true
>>>>>> COMPONENT TIMEOUT!!!
### end test
我做错了什么?如果我必须等待对组件的所有异步操作完成,我应该如何正确编写异步测试?
【问题讨论】:
【参考方案1】:不确定,为什么fixture.whenStable()
不自己等待delay (setTimeout)
。
但正常的Promise
或Observable
返回效果很好
但是你可以用任何一种方式解决它:
方法一:你可以使用tick()
手动等待fakeAync
it(`my test`, fakeAsync(() =>
console.log('### start test');
fixture.detectChanges();
// call a method which has async code
fixture.componentInstance.fakeTimeout();
tick(2100); // just more than the delay mentioned inside the component.
console.log('isStable', fixture.isStable());
fixture.whenStable().then(() =>
// here I must check smth only when all async operations are completed
console.log('### end test');
);
));
方法2:在spec文件中拥有自己的setTimeout
,使用done()
完成测试
it(`my test`, ((done) =>
console.log('### start test');
fixture.detectChanges();
// call a method which has async code
fixture.componentInstance.fakeTimeout();
setTimeout(()=>
console.log('isStable', fixture.isStable());
console.log('### end test');
done();
,2100)
));
【讨论】:
以上是关于Angular 2+,异步测试和 setTimeout的主要内容,如果未能解决你的问题,请参考以下文章
Angular 11:对 HttpInterceptor 进行单元测试 - 异步计时器或 AfterAll 错误
异步需要 AsyncTestZoneSpec - Angular
Jasmine 2.0 async done() 和 angular-mocks inject() 在同一个测试 it()