02 Jest测试框架--测试异步代码

390 阅读2分钟

在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中异步测试的全部内容了。

我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!