我在服务中有一个方法,要求返回之前恰好等待5000毫秒。我需要对该方法进行单元测试。我想使用sinon fakeTimers
模拟延迟,因为我不希望整个单元测试实际等待5000 ms。但是我有两个问题。
1)一旦使用sinon fakeTimers,测试就会冻结。当代码到达延迟线时,我正在寻找一种方法来滴答5000毫秒。
2)我如何“断言”该值是否恰好在5000毫秒(不是4999毫秒,不是5001毫秒)之后返回? (甚至有可能吗?)
class MyService {
async doSomething(){
await this.delay(5000)
return 'Done'
}
delay(millis: number) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, millis);
});
}
}
describe('My Service', ()=>{
it('should return done after 5s',async ()=>{
const clock = sinon.useFakeTimers(0)
clock.tick(5000)
const service = new MyService()
const ans = await service.doSomething()
expect(ans).to.equal('Done')
})
})
您可以查看How to test async functions with fake timers文档以获取更多信息。这是解决方案:
service.js
:
class MyService {
async doSomething() {
await this.delay(5000);
return 'Done';
}
delay(millis: number) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, millis);
});
}
}
export { MyService };
service.test.js
:
import { MyService } from './service';
import sinon from 'sinon';
import { expect } from 'chai';
describe('61695981', () => {
let clock;
before(() => {
clock = sinon.useFakeTimers();
});
after(() => {
clock.restore();
});
it('should pass', async () => {
const service = new MyService();
const ansPromise = service.doSomething();
clock.tick(5000);
const ans = await ansPromise;
expect(ans).to.equal('Done');
});
});
具有100%覆盖率的单元测试结果:
61695981
✓ should pass
1 passing (15ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
service.ts | 100 | 100 | 100 | 100 |
------------|---------|----------|---------|---------|-------------------