javascript - 如何使用 sinon.useFakeTimers 在 javascript 单元测试中设置超时
问题描述
我正在尝试测试以下方法:
endSocketConn(socket) {
if(!socket) {
return;
}
socket.setTimeout(5000, () => {
socket.destroy();
});
socket.end('commandToSend');
}
我需要测试的场景是如果超过 5 秒,那么 socket.destroy() 必须被调用一次
describe('Testing API | socketPool methods', async function () {
beforeEach(async function () {
let clock = sinon.useFakeTimers();
let socketMock = {
setTimeout: sinon.spy(),
destroy: sinon.spy(),
end: sinon.spy(),
};
});
afterEach(async function () {
clock && clock.restore();
});
describe('Testing endSocketConn() function', function () {
it('It should execute socket.destroy if timeout occurred after sending commandToSend', async function () {
let result;
let error = false;
try {
clock.tick(6000);
result = await file.endSocketConn(socketMock);
} catch (err) {
error = err;
}
expect(error).to.be.false;
sinon.assert.callCount(socketMock.setTimeout, 1);
sinon.assert.callCount(socketMock.end, 1);
sinon.assert.callCount(socketMock.destroy, 1);
// AssertError: expected spy to be called once but was called 0 times
});
});
知道为什么没有正确模拟超时吗?
解决方案
你不需要使用sinon.useFakeTimers()
,因为我们可以使用存根来实现一个与真实无关的方法setTimeout
。
例如
file.js
:
endSocketConn(socket) {
if (!socket) {
return;
}
socket.setTimeout(5000, () => {
socket.destroy();
});
socket.end('commandToSend');
},
};
export { file };
file.test.js
:
import sinon from 'sinon';
import { file } from './file';
describe('Testing API | EslSocketPoolHandler methods', function () {
let socketMock;
beforeEach(function () {
socketMock = {
setTimeout: sinon.stub(),
destroy: sinon.spy(),
end: sinon.spy(),
};
});
describe('Testing endSocketConn() function', function () {
it('It should execute socket.destroy if timeout occurred after sending commandToSend', function () {
socketMock.setTimeout.callsFake((ms, cb) => {
cb();
});
file.endSocketConn(socketMock);
sinon.assert.callCount(socketMock.setTimeout, 1);
sinon.assert.callCount(socketMock.end, 1);
sinon.assert.callCount(socketMock.destroy, 1);
});
});
});
单元测试结果:
Testing API | EslSocketPoolHandler methods
Testing endSocketConn() function
✓ It should execute socket.destroy if timeout occurred after sending commandToSend
1 passing (7ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 85.71 | 50 | 100 | 85.71 |
file.ts | 85.71 | 50 | 100 | 85.71 | 4
----------|---------|----------|---------|---------|-------------------
推荐阅读
- javascript - 如何在 javascript 的 addEventListener 函数中添加函数?
- react-native - React Native 中的基本功能
- java - Corda - 验证公证人抛出 java.lang.IllegalArgumentException
- postgresql - 如何确保 Postgres 中外键的有效性
- java - 完全原生的 Android 应用程序可以调用 Java 吗?
- python-3.x - 如何使用 Pyspark 创建列表 json?
- java - 如何自动检索任意 jar 的依赖项?
- swift - Swift Package Manager:Target可以访问其他Target的依赖
- javascript - 数据对象的子对象在记录之前不会被评估。Vue.js
- c# - 无法识别的元素:'binaryMessageEncoding'