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

Jest中pg Pool的mockResolvedValue仅首次测试可用,二次测试报错

解决Jest模拟pg Pool时第二个测试mockResolvedValue报错的问题

这种问题核心是Pool的mock函数没有在测试间正确重置,导致第二个测试中pool.query不再是Jest的mock函数实例。下面是具体的解决步骤和示例代码:

1. 正确配置pg库的mock

在测试文件顶部,确保模拟pg的Pool类时,其query方法始终是Jest mock函数:

jest.mock('pg', () => {
  const mockQuery = jest.fn();
  return {
    Pool: jest.fn(() => ({
      query: mockQuery,
      // 用到其他Pool方法时,同步在这里模拟
    }))
  };
});

2. 每个测试前重置mock环境

用beforeEach重置Pool和query的mock状态,保证每个测试都是独立干净的环境:

const { Pool } = require('pg');
// 提取query的mock函数,方便后续设置返回值
const mockQuery = jest.fn();

beforeEach(() => {
  // 重置Pool的mock,确保每次new Pool()都返回带新鲜mockQuery的实例
  Pool.mockClear();
  Pool.mockImplementation(() => ({
    query: mockQuery,
  }));
  // 重置query的调用记录、返回值等状态
  mockQuery.mockClear();
});

3. 编写独立的测试用例

现在两个测试可以各自设置不同的mock返回值,不会互相干扰:

test('test1: 查询返回初始数据', async () => {
  const pool = new Pool();
  // 设置test1专属的返回值
  mockQuery.mockResolvedValue({ rows: [{ id: 1, name: 'test_data' }] });

  // 调用你的业务逻辑代码
  const result = await yourPoolBasedFunction();

  expect(mockQuery).toHaveBeenCalledTimes(1);
  expect(result).toEqual([{ id: 1, name: 'test_data' }]);
});

test('test2: 查询返回另一组数据', async () => {
  const pool = new Pool();
  // 设置test2专属的返回值
  mockQuery.mockResolvedValue({ rows: [{ id: 2, name: 'another_data' }] });

  const result = await yourPoolBasedFunction();

  expect(mockQuery).toHaveBeenCalledTimes(1);
  expect(result).toEqual([{ id: 2, name: 'another_data' }]);
});

额外排查点

  • 不要在测试中直接覆盖pool.query的引用(比如pool.query = someFunc),这会替换掉Jest的mock函数
  • 如果你的业务代码是模块导入时就创建了Pool单例,需要在beforeEach中用jest.resetModules()重新导入模块,确保每次测试都拿到新的Pool实例:
    beforeEach(() => {
      jest.resetModules();
      // 在这里重新导入业务模块
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 22:43:19