在下面的例子中,我有两个函数doTask和doSubTask。两者都是异步的,但由于一些业务需要,我需要解雇& &;忘记两次使用不同参数的doSubTask
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
const doTask = async (taskId) => {
await wait(taskId)
doSubTask(taskId * 3)
doSubTask(taskId * 5)
console.log('end task :' + taskId)
}
const doSubTask = async (subTaskId) => {
await wait(subTaskId)
console.log('end subTask :' + subTaskId)
}
doTask(2000)
我如何为doTask写一个测试用例,并断言doSubTask已经被调用了两次?
这是一个代码示例,你可以在runkit.com上运行它
require("@fatso83/mini-mocha").install()
const sinon = require("sinon@7.5.0")
const referee = require("@sinonjs/referee")
const chai = require('chai')
chai.use(require('sinon-chai'))
const expect = chai.expect
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
const doTask = async (taskId) => {
await wait(taskId)
doSubTask(taskId * 3)
doSubTask(taskId * 5)
console.log('end task :' + taskId)
}
const doSubTask = async (subTaskId) => {
await wait(subTaskId)
console.log('end subTask :' + subTaskId)
}
const app = {
doTask,
doSubTask,
}
describe("stub", function () {
it("doSubTask should be called twice", async function () {
const doSubTaskSpy = sinon.spy(app, 'doSubTask')
await doTask(2000)
expect(doSubTaskSpy).to.be.calledTwice()
})
})
上面代码的输出是:
stub
end task :2000
❌ doSubTask should be called twice (Failed with: "expecte…e been called exactly twice, but it was called 0 times")
end subTask :6000
end subTask :10000
我们应该使用rewire包来要求模块和存根doSubTask
函数。此外,当promise
和setTimeout
同时使用时,我们应该使用这种方法来使用假计时器和提前时间。
。
index.js
:
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const doTask = async (taskId) => {
await wait(taskId);
doSubTask(taskId * 3);
doSubTask(taskId * 5);
console.log('end task :' + taskId);
};
const doSubTask = async (subTaskId) => {
await wait(subTaskId);
console.log('end subTask :' + subTaskId);
};
const app = {
doTask,
doSubTask,
};
module.exports = app;
index.test.js
:
const rewire = require('rewire');
const sinon = require('sinon');
describe('stub', function () {
let clock;
before(() => {
clock = sinon.useFakeTimers();
});
after(() => {
clock.restore();
});
it('doSubTask should be called twice', async function () {
const doSubTaskStub = sinon.stub();
const mod = rewire('./');
mod.__set__('doSubTask', doSubTaskStub);
const promise = mod.doTask(2000);
clock.tick(2010);
await promise;
sinon.assert.calledTwice(doSubTaskStub);
sinon.assert.calledWithExactly(doSubTaskStub, 6000);
sinon.assert.calledWithExactly(doSubTaskStub, 10000);
});
});
测试结果:
stub
end task :2000
✓ doSubTask should be called twice (738ms)
1 passing (743ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 84.62 | 100 | 75 | 81.82 |
index.js | 84.62 | 100 | 75 | 81.82 | 11-12
----------|---------|----------|---------|---------|-------------------