测试异步代码
为你的测试返回一个Promise,则Jest会等待Promise的resove状态 If the promise is rejected, the test will fail.
For example, let’s say that fetchData
returns a promise that is supposed to resolve to the string 'peanut butter'
. 我们可以使用下面的测试代码︰
或者,您可以在测试中使用 async
和 await
。 写异步测试用例时,可以在传递给test
的函数前面加上async
。 例如,可以用来测试相同的 fetchData
方案︰
test('the data is peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
} catch (e) {
expect(e).toMatch('error');
}
});
你也可以将 async
and await
和 .resolves
or .rejects
一起使用。
上述示例中, and await
实际上是一种基于Promise的异步语法糖。
caution
如果期望Promise被Reject,则需要使用 .catch
方法。 请确保添加 expect.assertions
来验证一定数量的断言被调用。 否则,一个fulfilled状态的Promise不会让测试用例失败。
test('the fetch fails with an error', () => {
expect.assertions(1);
return fetchData().catch(e => expect(e).toMatch('error'));
});
If you don’t use promises, you can use callbacks. For example, let’s say that fetchData
, instead of returning a promise, expects a callback, i.e. fetches some data and calls callback(null, data)
when it is complete. 你期望返回的数据是一个字符串 'peanut butter'
默认情况下,一旦到达运行上下文底部Jest测试立即结束。 这样意味着这个测试将不能按预期工作。
问题在于一旦fetchData
执行结束,此测试就在调用回调函数前结束了(因为同步代码结束后,才是异步拿到的数据)。
还有另一种形式的 test
可以解决这个问题。 使用单个参数调用 done
,而不是将测试放在一个空参数的函数。 Jest会等done
回调函数被调用执行结束后,再结束测试。
test('the data is peanut butter', done => {
function callback(error, data) {
if (error) {
done(error);
return;
try {
done();
} catch (error) {
done(error);
}
}
fetchData(callback);
});
若 expect
执行失败,它会抛出一个错误,后面的 done()
不再执行。 若我们想知道测试用例为何失败,我们必须将 expect
放入 try
中,将 error 传递给 catch
中的 done
函数。 否则,最后控制台将显示一个超时错误失败,不能显示我们在 expect(data)
中接收的值。
注意: done()
不应与Promises混合,因为这会导致您测试中的内存泄漏。
您还可以使用 .resolves
匹配器在您期望的声明,Jest 会等待这一 Promise 来解决。 如果 Promise 被拒绝,则测试将自动失败。
一定不要忘记把整个断言作为返回值返回⸺如果你忘了return
语句的话,在 fetchData
返回的这个 promise 变更为 resolved 状态、then() 有机会执行之前,测试就已经被视为已经完成了。
如果你希望Promise返回rejected,你需要使用 .rejects
匹配器。 它和 .resolves
匹配器是一样的使用方式。 如果 Promise 被拒绝,则测试将自动失败。
test('the fetch fails with an error', () => {
});