You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest测试既不返回Promise也不接受回调的异步函数问题

测试无Promise/回调的异步函数的解决方案

你的问题核心在于getUser里的异步操作(fetch+setTimeout)还没完成,测试就执行了断言。下面提供两种可行的解决思路:

方法一:改造原函数(推荐)

最规范的做法是让异步函数返回Promise,这样测试就能明确追踪异步状态。修改index.js如下:

// index.js
export let usersList = [];

export function getUser() {
  return fetch("https://jsonplaceholder.typicode.com/users")
    .then((x) => x.json())
    .then((users) => {
      return new Promise(resolve => {
        setTimeout(() => {
          usersList = users;
          resolve(); // 通知Promise完成
        }, 2000);
      });
    });
}

getUser();

对应的测试用例可以用async/await来等待异步完成:

// index.test.js
const { getUser, usersList } = require("./index");

// 模拟fetch,避免真实网络请求
global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve(new Array(10).fill({})) // 模拟10个用户数据
  })
);

it("should fetch users and assign to usersList", async () => {
  await getUser(); // 等待异步操作完成
  expect(usersList.length).toBe(10);
});

方法二:不修改原函数,用Jest的定时器模拟

如果无法改动原函数,可以通过Jest的假定时器和fetch模拟来实现测试:

// index.test.js
const { getUser, usersList } = require("./index");

// 模拟fetch
global.fetch = jest.fn(() =>
  Promise.resolve({
    json: () => Promise.resolve(new Array(10).fill({}))
  })
);

beforeEach(() => {
  jest.useFakeTimers(); // 启用假定时器
  jest.clearAllMocks(); // 清空mock
  usersList.length = 0; // 重置用户列表
});

afterEach(() => {
  jest.useRealTimers(); // 恢复真实定时器
});

it("should fetch users and assign to usersList", async () => {
  getUser();
  
  // 先让fetch的Promise链执行到setTimeout这一步
  await Promise.resolve();
  // 快进2000ms,触发setTimeout里的逻辑
  jest.advanceTimersByTime(2000);
  // 再等待一次微任务,确保赋值操作完成
  await Promise.resolve();

  expect(usersList.length).toBe(10);
  expect(fetch).toHaveBeenCalledTimes(1);
});

注意事项

  • 无论哪种方法,都要模拟fetch,避免测试依赖真实网络请求,保证测试的稳定性和速度。
  • 方法一的优势在于让异步逻辑更清晰,后续维护和测试都更简单,是优先推荐的方案。

内容的提问来源于stack exchange,提问作者Sameer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:48:26