Testing Asynchronous Code
最常见的异步模式是回调函数。
例如,假设您有一个 fetchData(callback)
函数,获取一些数据并在完成时调用 callback(data)
。 你期望返回的数据是一个字符串 'peanut butter'
默认情况下,Jest 测试一旦执行到末尾就会完成。 那意味着该测试将不会按预期工作:
问题在于一旦fetchData
执行结束,此测试就在没有调用回调函数前结束。
还有另一种形式的 test
,解决此问题。 使用单个参数调用 done
,而不是将测试放在一个空参数的函数。 Jest会等done
回调函数执行结束后,结束测试。
test('the data is peanut butter', done => {
function callback(data) {
try {
expect(data).toBe('peanut butter');
done();
done(error);
}
}
fetchData(callback);
});
若 执行失败,它会抛出一个错误,后面的 done()
不再执行。 若我们想知道测试用例为何失败,我们必须将 expect
放入 try
中,将 error 传递给 catch
中的 done
函数。 否则,最后控制台将显示一个超时错误失败,不能显示我们在 expect(data)
中接收的值。
If your code uses promises, there is a more straightforward way to handle asynchronous tests. Return a promise from your test, and Jest will wait for that promise to resolve. 如果承诺被拒绝,则测试将自动失败。
举个例子,如果 fetchData
不使用回调函数,而是返回一个 Promise,其解析值为字符串 'peanut butter'
我们可以这样测试:
一定不要忘记把 promise 作为返回值⸺如果你忘了 return
语句的话,在 fetchData
返回的这个 promise 被 resolve、then() 有机会执行之前,测试就已经被视为已经完成了。
If you expect a promise to be rejected, use the .catch
method. 请确保添加 expect.assertions
来验证一定数量的断言被调用。 Otherwise, a fulfilled promise would not fail the test.
test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(e => expect(e).toMatch('error'));
一定不要忘记把整个断言作为返回值返回⸺如果你忘了return
语句的话,在 fetchData
返回的这个 promise 变更为 resolved 状态、then() 有机会执行之前,测试就已经被视为已经完成了。
If you expect a promise to be rejected, use the matcher. 它参照工程 .resolves
匹配器。 如果 Promise 被拒绝,则测试将自动失败。
test('the fetch fails with an error', () => {
return expect(fetchData()).rejects.toMatch('error');
});
或者,您可以在测试中使用 async
和 await
。 To write an async test, use the async
keyword in front of the function passed to test
. 例如,可以用来测试相同的 fetchData
方案︰
You can combine async
and await
with .resolves
or .rejects
.
test('the data is peanut butter', async () => {
await expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
await expect(fetchData()).rejects.toThrow('error');
In these cases, async
and are effectively syntactic sugar for the same logic as the promises example uses.