在JavaScript中异步代码很常见,当我们要测试异步代码的时候, Jest需要知道何时测试完成,Jest有多种方法进行异步代码测试。
Promises
在我们的test语句中返回一个Promise,Jest会等到Promise结束之后,在执行后续用例。
假设我们有个fetchData函数,返回个Promise,我们可以在fetchData.then或者fetchData.catch中进行测试。
resolve情况
function fetchData(){
return Promise.resolve({a:1})
}
test('异步测试', () => {
return fetchData().then(data => {
expect(data).toEqual({a:1});
});
});
reject情况
function fetchData(){
return Promise.reject('error')
}
test('异步测试', () => {
return fetchData().catch(data => {
expect(data).toEqual('error');
});
});
那假如fetchData 最终reject了,如下代码也会通过
function fetchData(){
return Promise.reject('error')
}
test('异步测试', () => {
return fetchData().then(data => {
expect(data).toEqual({a:1});
}).catch(() =>{
});
});
但是这不符合我们预期,我们.then中的断言并没有被执行,我们期望断言执行了1次。 可以通过expect.assertions(num)设置断言执行次数。如下,我们设置断言要执行一次, 但是实际执行了0次,该条用例会失败。
function fetchData(){
return Promise.reject('error')
}
test('异步测试', () => {
expect.assertions(1)
return fetchData().then(data => {
expect(data).toEqual({a:1});
}).catch(() =>{
});
});
Async/Await
我们也可以通过async/await来完成异步测试,和我们平时使用并没有差别。
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 {
await fetchData();
} catch (e) {
expect(e).toMatch('error');
}
});
也可以结合 async/await 和 .resolves/.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.toMatch('error');
});
Callbacks
有时候异步并不是返回一个Promise,而是传递回调函数,比如fetchData定时3秒之后调用callback, 并没有返回promise,那么jest在执行完fetchData函数后会立即结束进行后续测试,所以下面的测试不会生效, 在执行 npm run jest后,立即显示用例测试通过,并不会像预期那样3秒之后才出结果。
function fetchData(callback){
setTimeout(() => {
callback({a:1})
}, 3000)
}
//此示例不会工作
test('回调测试', () => {
function callback(data){
expect(data).toEqual({a:2})
}
fetchData(callback)
});
解决方法就是在测试函数中加一个名为 done的参数,并在测试完毕后,调用done()
test('回调测试', done => {
function callback(data){
expect(data).toEqual({a:2})
done()
}
fetchData(callback)
});
.resolves / .rejects
我们也可以在expect后使用.resolves / .rejects,Jest会等到Promise结束执行后面的匹配器
function fetchData(){
return Promise.resolve({a:1})
}
test('回调测试', () => {
return expect(fetchData()).resolves.toEqual({a:1})
});
但是确保必须使用了return语句,否则无效,只有有返回值,Jest才能等待返回的Promise结束,如果没有返回值, 则同步代码立即执行完毕了,就进入后续的测试了
function fetchData(){
return Promise.resolve({a:1})
}
//用例依然通过
test('回调测试', () => {
expect(fetchData()).resolves.toEqual({a:2})
});
好了,以上就是Jest中异步测试的全部内容了。
我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!