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

Jest中AWS SDK v3单元测试Mock跨describe块无法重置的问题

在不同describe测试块中重置aws-sdk-client-mock的解决方案

问题场景

我在对Lambda函数进行单元测试时,使用aws-sdk-client-mock库实现Mock功能。测试Lambda的5xx状态码时,需要移除Mock以触发凭证错误(CredentialsProviderError: Could not load credentials from any providers),但第一个describe块的Mock仍处于活跃状态,导致第二个测试用例无法正常执行。只有注释掉第一个describe块(完全不使用Mock)时,第二个测试才能正常运行。

原始测试代码如下:

import { APIGatewayProxyResult } from 'aws-lambda';
import { main } from "../../lib/src/lambda/approval-handler";
import { mockClient } from "aws-sdk-client-mock";
import {
    CodePipelineClient
} from "@aws-sdk/client-codepipeline";
import { event, queryStringParameters } from "../utils/lambda-event"


describe("Successful Approve or Deny", () => { // 此测试正常运行
    const pipelineClientMock = mockClient(CodePipelineClient);

    beforeEach(() => {
        pipelineClientMock.reset();
    });

    it("returns a 301 response with a redirect location if all required query parameters are provided", async () => {
        pipelineClientMock.resolves({})
        const result: APIGatewayProxyResult = await main(event);
        expect(result.statusCode).toEqual(301);
    });
})


describe("When Approval or Deny is not sent successfully", () => { // 此测试失败,因为Mock仍活跃
    it("returns a 502 error response if any of the required query parameters are missing", async () => {
        const result: APIGatewayProxyResult = await main(event);
        expect(result.statusCode).toEqual(502);
    });
});

解决方法

aws-sdk-client-mock创建的Mock是全局生效的,reset()方法仅能重置Mock的调用记录和预设逻辑,无法销毁Mock本身。要彻底移除Mock,需要在测试块结束时调用restore()方法。

1. 在第一个测试块中添加afterAll钩子销毁Mock

修改第一个describe块,在测试全部结束后调用restore(),彻底销毁Mock,让后续测试块能使用真实的客户端逻辑:

describe("Successful Approve or Deny", () => {
    const pipelineClientMock = mockClient(CodePipelineClient);

    beforeEach(() => {
        pipelineClientMock.reset();
    });

    // 测试块结束后销毁Mock
    afterAll(() => {
        pipelineClientMock.restore();
    });

    it("returns a 301 response with a redirect location if all required query parameters are provided", async () => {
        pipelineClientMock.resolves({})
        const result: APIGatewayProxyResult = await main(event);
        expect(result.statusCode).toEqual(301);
    });
})

2. 确保第二个测试块不创建Mock

第二个测试块不需要任何Mock配置,直接执行测试逻辑即可。此时调用CodePipelineClient会因为没有凭证抛出预期的错误,进而触发Lambda返回5xx状态码的逻辑。

扩展:多测试块的Mock隔离方案

如果后续还有需要使用Mock的测试块,可以遵循每个测试块独立创建和销毁Mock的原则:

  • 在beforeAll中创建Mock
  • 在afterAll中调用restore()销毁Mock
  • 在beforeEach中调用reset()重置Mock状态

这样就能保证每个测试块的Mock互不干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:17:45