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

Jest中mockResolvedValueOnce一次性实现跨测试残留问题

Jest中未执行的mockResolvedValueOnce实现跨测试残留问题

我在为处理SNS主题通知的AWS Lambda编写测试:当特定特性标志关闭时,Lambda会直接返回。但测试1的mock实现会残留到测试2,导致本该正常通过的测试失败。

处理程序最小可复现代码(MWE)

export async handler(event) {
  for (record of event.Records) {
    try {
      const {
        applicationId
      } = JSON.parse(JSON.parse(record.body).Message);

      const shouldHandleNotification = await isFeatureFlagOn(PARAMETER_STORE_ARN, FEATURE_FLAG);
      if (!shouldHandleNotification) {
        console.info(`Flag [SHOULD_HANDLE_NOTIFICATION] is off, skipping notification handling.`);
        return;
      }

      const applicationData = await getApplicationData(applicationId);
      if (applicationData.type == "human") {
        // handle application
      } else if (application.type == "viltrumite") {
        // handle application
      } else {
        throw new Error(`Cannot handle application type [${applicationData.type}]`);
      }
    } catch (e) {
      console.error(`Cannot handle record. Error message: ${e.message}`)
    }
  }
}

测试代码最小可复现示例

const mockIsFeatureFlagOn = jest.fn();
jest.mock("moduleIsFeatureFlagOn", () => ({
  isFeatureFlagOn: mockIsFeatureFlagOn,
}));

const mockGetApplicationData = jest.fn();
jest.mock("moduleGetApplicationData", () => ({
  getApplicationData: mockGetApplicationData,
}));

describe("SNSNotificationHandler", () => {
    beforeEach(() => {
      jest.clearAllMocks();
    });

  // 测试1
  it("特性标志关闭时不处理通知", async () => {
    mockIsFeatureFlagOn.mockResolvedValueOnce(false);
    mockGetApplicationData.mockResolvedValueOnce({
      type: "unknown"
    });

    await handler(EVENT_WITH_APPLICATION_DATA);

    mockIsFeatureFlagOn.toHaveBeenCalledWith(PARAMETER_STORE_ARN, FEATURE_FLAG);
    mockGetApplicationData.not.toHaveBeenCalled();
  });

  // 测试2
  it("处理viltrumite类型应用", async () => {
    mockIsFeatureFlagOn.mockResolvedValueOnce(true);
    mockGetApplicationData.mockResolvedValueOnce({
      type: "viltrumite"
    });

    await handler(EVENT_WITH_APPLICATION_DATA);

    mockIsFeatureFlagOn.toHaveBeenCalledWith(PARAMETER_STORE_ARN, FEATURE_FLAG);
    mockGetApplicationData.toHaveBeenCalled();
  });
}

测试2失败,因为mockGetApplicationData的mock实现未在测试1后清除,残留到测试2中返回{ type: "unknown" }而非预期的{ type: "viltrumite" }。测试1中mockGetApplicationData从未被调用,即使使用jest.clearAllMocks(),其实现仍会残留。我可以手动清除该mock的实现解决问题,但想了解背后原因:

已知jest.clearAllMocks设计上不会移除mock实现,但疑惑为何测试1中设置的、未被执行的mockResolvedValueOnce一次性实现会渗透到测试2中?未执行的一次性实现不应局限于当前测试,让mock回到jest.fn()的初始状态吗?

注:mockFn.mockResolvedValueOnce(value)是jest.fn().mockImplementationOnce(() => Promise.resolve(value))的简写,根据Jest文档:当用.mockImplementationOnce()定义的实现耗尽后,会执行jest.fn(() => defaultValue)或.mockImplementation(() => defaultValue)设置的默认实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:33:32