如何用 sinon 模拟延迟?
How to mock delay with sinon?
我在服务中有一个方法需要在返回前准确等待 5000 毫秒。
我需要对该方法进行单元测试。我想使用 sinon fakeTimers
模拟延迟,因为我不希望整个单元测试实际等待 5000 毫秒。
但是我有两个问题。
1) 一旦我使用 sinon fakeTimers,测试就会冻结。我正在寻找一种在代码到达延迟线时勾选 5000 毫秒的方法。
2) 我如何 "assert" 确保值恰好在 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 |
------------|---------|----------|---------|---------|-------------------
我在服务中有一个方法需要在返回前准确等待 5000 毫秒。
我需要对该方法进行单元测试。我想使用 sinon fakeTimers
模拟延迟,因为我不希望整个单元测试实际等待 5000 毫秒。
但是我有两个问题。
1) 一旦我使用 sinon fakeTimers,测试就会冻结。我正在寻找一种在代码到达延迟线时勾选 5000 毫秒的方法。
2) 我如何 "assert" 确保值恰好在 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 |
------------|---------|----------|---------|---------|-------------------