异步测试

异步测试

JavaScript代码中常常会包含异步代码,当测试异步代码时,Jest需要知道什么时候异步代码执行完成,在异步代码执行完之前,它会去执行其他的测试代码。Jest提供了多种方式测试异步代码。

回调函数

当执行到测试代码的尾部时,Jest即认为测试完成。因此,如果存在异步代码,Jest不会等待回调函数执行。要解决这个问题,在测试函数中我们接受一个参数叫做doneJest将会一直等待,直到我们调用done()。如果一直不调用done(),则此测试不通过。

// async/fetch.js
export const fetchApple = callback => {
  setTimeout(() => callback("apple"), 300);
};

// async/fetch.test.js
import { fetchApple } from "./fetch";

test("the data is apple", done => {
  expect.assertions(1);
  const callback = data => {
    expect(data).toBe("apple");
    done();
  };

  fetchApple(callback);
});

expect.assertions(1)验证当前测试中有1处断言会被执行,在测试异步代码时,能确保回调中的断言被执行。

Promise

如果异步代码返回Promise对象,那我们在测试代码直接返回该Promise即可,Jest会等待其resolved,如果rejected则测试不通过。

test("the data is banana", () => {
  expect.assertions(1);
  return fetchBanana().then(data => expect(data).toBe("banana"));
});

如果期望promiserejected状态,可以使用 .catch()

test("the fetch fails with an error", () => {
  expect.assertions(1);
  return fetchError().catch(e => expect(e).toMatch("error"));
});

除此之外,还可以使用上文中提到的 .resolves.rejects

Async/Await

如果异步代码返回promise,我们还可以使用async/await

test("async: the data is banana", async () => {
  expect.assertions(1);
  const data = await fetchBanana();
  expect(data).toBe("banana");
});

test("async: the fetch fails with an error", async () => {
  expect.assertions(1);
  try {
    await fetchError();
  } catch (e) {
    expect(e).toMatch("error");
  }
});

也可以将aysnc/awiat.resolves.rejects 结合:

test("combine async with `.resolves`", async () => {
  expect.assertions(1);
  await expect(fetchBanana()).resolves.toBe("banana");
});
上一页