【发布时间】:2018-04-26 19:21:48
【问题描述】:
Javascript Jest 测试框架documentation 说我需要在我的回调中添加done() 来测试异步函数,否则测试完成后函数会返回,所以测试会失败。我已将 Jest 添加到我的 package.json 中,以及以下两个文件:
src.js:
function fetchData(cb) {
setTimeout(cb, 2000, 'peanut butter')
}
module.exports = fetchData
src.test.js:
const fetchData = require('./src')
test('the data is peanut butter', () => {
function callback(data) {
expect(data).toBe('peanut butter')
// no done() method!
}
fetchData(callback);
})
我使用上面的代码通过了测试,但我认为我的测试应该失败,因为我的测试文件中没有done()。我的fetchData() 方法不是异步的吗?
编辑:按照 Nicholas 的回答,我将代码更改为:
src.js:
function fetchData(cb) {
setTimeout(cb, 2000, 'peanut')
}
module.exports = fetchData
src.test.js:
const fetchData = require('./src')
test('the data is peanut butter', () => {
function callback(data) {
expect(data).toBe('peanut butter')
done()
}
fetchData(callback);
})
测试运行者应根据 Jest 文档评估期望/断言并失败(花生通过,花生酱预期),但仍显示通过测试。
此外,Jest 文档说:
If done() is never called, the test will fail, which is what you want to happen
测试在回调中有和没有 done() 方法的情况下,以及在有和没有传递给回调的正确 (peanut butter) 参数的情况下都通过(即所有四个变体都通过)。
【问题讨论】:
-
如果您不将
done作为参数传递,则代码被认为是同步的并且不会等待。 在你的断言有机会运行之前,测试被认为是成功的 -
不管我设置了多长时间,测试运行器都会等待计时器完成,然后在我的控制台中报告测试结果。但是文档说我需要做一些特别的事情来处理异步代码——期望对象肯定是异步执行的(作为
setTimeout()的回调) -
测试运行器(或者更具体地说是 Node 本身)在终止进程之前等待最后注册的
setTimeout回调到期。尝试创建一个空文件并在其中放入一个setTimeout。您会看到它在触发之前不会退出进程 -
Jest 有一个完全的陷阱,它修改了计时函数的行为。我已经编辑了我的答案以包含一个工作示例和对讨论该行为的问题的引用
-
同样,在您包含的编辑中,您没有将
done作为参数传递给test。done也应该作为参数传递,除了在你完成测试时也会被调用。看看我的例子,运行它,你就会明白这一点。注意第 8 行,我将test作为参数传递
标签: javascript asynchronous jestjs