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
相关产品推荐
相关产品推荐

