javascript单元测试用例中如何覆盖setInterval
How to cover setInterval in the unit test case in javascript
您好,我正在编写此功能的单元测试用例。当我 运行 来自单元测试用例的这个函数时,它会覆盖所有语句,但 setInterval
完整行未被覆盖。
有谁知道如何在 javascript 中覆盖它?我在用摩卡
const open = async function (config) {
...... set of lines..
let retryIn = setInterval(async () => {
try {
client = await connect(config);
clearInterval(retryIn);
return client;
} catch (err) {
//error
}
}, 20000);
};
我只是这样称呼它
it("###test", async () => {
open(config);
});
});
有人发布了一个关于假计时器的答案,然后删除了它,答案是正确的,所以我重新发布了。
您可以使用 sinonjs
创建假计时器
Fake timers are synchronous implementations of setTimeout and friends
that Sinon.JS can overwrite the global functions with to allow you to
more easily test code using them
但是从你的代码来看,你似乎在尝试测试异步代码,在 mocha 中,这可以这样实现
describe('somthing', () => {
it('the result is 2', async () => {
const x = await add(1, 1)
expect(x).to.equal(4);
});
});
更接近您的代码
async function open() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('done')
}, 1000);
});
};
describe('somthing', () => {
it('###test', async () => {
const x = await open()
chai.expect(x).to.equal("done");
});
});
换行到Promise
const open = async function (config) {
...... set of lines..
return new Promise((resolve, reject) => {
let retryIn = setInterval(async () => {
client = await connect(asConfigParam);
clearInterval(retryIn);
return client;
}, 20000);
return resolve(retryIn);
});
};
it("###test", async () => {
const result = await open(config);
console.log('result', result)
});
首先,如果你想重试一个失败的任务,你不应该使用setInterval
。您应该改用 setTimeout
。
除此之外,您不能 return 来自经典回调基函数的值,例如 setInterval
或 setTimeout
。因此,在其当前形式中,在调用 open
时承诺 returned 将在建立任何连接之前得到解决。
使用 await
/async
您可以为这种情况创建一个干净简单的设置:
function wait(seconds) {
return new Promise((resolve, _) => setTimeout(resolve, seconds))
}
async function connect() {
throw new Error('failed')
}
async function open(config) {
let client;
while (client === undefined /* || retries > maxRetries*/ ) {
try {
client = await connect(config);
} catch (err) {
// if connection failed due to an error, wait n seconds and retry
console.log('failed wait 2 seconds for reconnect');
await wait(2000)
// ++retries
}
}
if (!client) {
throw new Error('connection failed due to max number of retries reached.')
}
return client
}
async function main() {
let connection = await open()
}
main().catch(err => console.log(err))
您可以通过添加重试限制来进一步扩展此代码段。有关如何实现这一目标的粗略想法,请参阅评论。
要测试上面的代码,您可以这样写:
it("###test", function() {
return open(config);
});
您好,我正在编写此功能的单元测试用例。当我 运行 来自单元测试用例的这个函数时,它会覆盖所有语句,但 setInterval
完整行未被覆盖。
有谁知道如何在 javascript 中覆盖它?我在用摩卡
const open = async function (config) {
...... set of lines..
let retryIn = setInterval(async () => {
try {
client = await connect(config);
clearInterval(retryIn);
return client;
} catch (err) {
//error
}
}, 20000);
};
我只是这样称呼它
it("###test", async () => {
open(config);
});
});
有人发布了一个关于假计时器的答案,然后删除了它,答案是正确的,所以我重新发布了。
您可以使用 sinonjs
创建假计时器
Fake timers are synchronous implementations of setTimeout and friends that Sinon.JS can overwrite the global functions with to allow you to more easily test code using them
但是从你的代码来看,你似乎在尝试测试异步代码,在 mocha 中,这可以这样实现
describe('somthing', () => {
it('the result is 2', async () => {
const x = await add(1, 1)
expect(x).to.equal(4);
});
});
更接近您的代码
async function open() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('done')
}, 1000);
});
};
describe('somthing', () => {
it('###test', async () => {
const x = await open()
chai.expect(x).to.equal("done");
});
});
换行到Promise
const open = async function (config) {
...... set of lines..
return new Promise((resolve, reject) => {
let retryIn = setInterval(async () => {
client = await connect(asConfigParam);
clearInterval(retryIn);
return client;
}, 20000);
return resolve(retryIn);
});
};
it("###test", async () => {
const result = await open(config);
console.log('result', result)
});
首先,如果你想重试一个失败的任务,你不应该使用setInterval
。您应该改用 setTimeout
。
除此之外,您不能 return 来自经典回调基函数的值,例如 setInterval
或 setTimeout
。因此,在其当前形式中,在调用 open
时承诺 returned 将在建立任何连接之前得到解决。
使用 await
/async
您可以为这种情况创建一个干净简单的设置:
function wait(seconds) {
return new Promise((resolve, _) => setTimeout(resolve, seconds))
}
async function connect() {
throw new Error('failed')
}
async function open(config) {
let client;
while (client === undefined /* || retries > maxRetries*/ ) {
try {
client = await connect(config);
} catch (err) {
// if connection failed due to an error, wait n seconds and retry
console.log('failed wait 2 seconds for reconnect');
await wait(2000)
// ++retries
}
}
if (!client) {
throw new Error('connection failed due to max number of retries reached.')
}
return client
}
async function main() {
let connection = await open()
}
main().catch(err => console.log(err))
您可以通过添加重试限制来进一步扩展此代码段。有关如何实现这一目标的粗略想法,请参阅评论。
要测试上面的代码,您可以这样写:
it("###test", function() {
return open(config);
});