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

如何在Jest+TypeScript中实现Postgres Pool的可定制Mock

解决方案

要在不同测试用例中定制Postgres Pool的query方法返回值,核心是将mock的query函数暴露出来,让每个测试都能独立配置。以下是具体实现步骤:

1. 重构Mock逻辑

直接导入pg模块并mock,用jest.mocked获取类型安全的mock对象,避免闭包导致无法访问内部mock函数:

import { describe, expect, test, jest, beforeEach } from "@jest/globals";
import { checkLimits } from "./db";
import { MINUTES } from "./constants";
import { Pool } from "pg";

// Mock整个pg模块
jest.mock("pg");
// 获取类型安全的Pool构造函数mock
const MockPool = jest.mocked(Pool);
// 声明全局可用的mock query函数
let mockQuery: jest.Mock;

2. 初始化测试前置条件

在beforeEach中重置所有mock,确保每个测试用例的mock状态独立:

beforeEach(() => {
  // 重置Pool构造函数的mock记录
  MockPool.mockClear();
  // 创建新的mock query函数
  mockQuery = jest.fn();
  // 让Pool构造函数返回带有mock query的实例
  MockPool.mockReturnValue({
    query: mockQuery,
  } as unknown as InstanceType<typeof Pool>);
});

3. 在测试用例中定制返回值

现在可以直接在每个测试里用mockQuery.mockReturnValueOnce设置专属返回值:

describe("checkLimits", () => {
  test("allows reasonable usage by address", async () => {
    mockQuery.mockReturnValueOnce({
      rows: [
        {
          timestamps: [Date.now() - 10 * MINUTES],
        },
      ],
    });
    await checkLimits("abcdef");
    // 可选:添加断言验证query调用情况
    expect(mockQuery).toHaveBeenCalled();
  });

  test("also allows more usage", async () => {
    mockQuery.mockReturnValueOnce({
      rows: [
        {
          timestamps: [
            Date.now() - 10 * MINUTES,
            Date.now() - 3 * MINUTES,
            Date.now() - 2 * MINUTES,
          ],
        },
      ],
    });
    await checkLimits("abcdef");
    expect(mockQuery).toHaveBeenCalled();
  });
});

关键说明

  • 避免了闭包封装mock导致的外部无法访问问题,直接将mockQuery暴露为全局变量。
  • beforeEach确保每个测试用例的mock都是全新的,不会出现测试间的状态污染。
  • jest.mocked解决了TypeScript的类型校验问题,无需额外复杂的类型断言。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 14:12:38