如何用Jest自动化测试CDK创建、API Gateway触发的Lambda函数?
为API Gateway+Lambda编写预部署测试套件的步骤
作为首次搭建测试流程的开发者,你可以按以下步骤实现预部署测试,确保Lambda功能正常再执行部署:
1. 准备测试工具与依赖
先把必要的测试工具装到位:
- 安装
jest(主流JavaScript/TypeScript测试框架)、aws-sdk-client-mock(用来模拟AWS服务调用,避免触发真实资源)、@types/jest(TypeScript类型支持) - 项目根目录初始化测试配置,比如用
jest --init快速生成jest.config.js
2. 编写Lambda单元测试
针对你的Lambda handler,重点覆盖成功调用Step Function和调用失败两种核心场景,示例代码如下:
import { handler } from '../src/lambda/example'; import { mockClient } from 'aws-sdk-client-mock'; import { SFNClient, StartExecutionCommand } from '@aws-sdk/client-sfn'; // 初始化Step Function客户端的模拟实例 const sfnMock = mockClient(SFNClient); describe('Example Lambda Handler', () => { // 每个测试前重置模拟状态,设置测试用的环境变量 beforeEach(() => { sfnMock.reset(); process.env.STEP_FUNCTION_ARN = 'test-state-machine-arn'; }); test('成功调用Step Function时返回200', async () => { // 模拟Step Function调用成功的响应 sfnMock.on(StartExecutionCommand).resolves({}); const testEvent = { body: JSON.stringify({ key: 'value' }) }; const result = await handler(testEvent, {}); expect(result.statusCode).toBe(200); expect(result.body).toBe('Success!'); // 验证Step Function确实被调用了一次 expect(sfnMock.calls()).toHaveLength(1); }); test('Step Function调用失败时返回500', async () => { // 模拟Step Function调用失败 sfnMock.on(StartExecutionCommand).rejects(new Error('SFN执行出错')); const testEvent = { body: JSON.stringify({ key: 'value' }) }; const result = await handler(testEvent, {}); expect(result.statusCode).toBe(500); expect(result.body).toContain('Problem executing step function'); }); });
3. 配置CDK预部署钩子
把测试流程和cdk deploy绑定,确保部署前自动跑测试:
- 在项目根目录的
cdk.json里添加hooks配置:
{ "hooks": { "preDeploy": "npm run test" } }
- 确保
package.json里有对应的测试脚本:
{ "scripts": { "test": "jest" } }
这样以后执行cdk deploy --all时,会先自动运行所有测试,只有测试全部通过才会继续部署流程。
4. 可选:补充API Gateway集成测试
如果要验证API Gateway和Lambda的集成是否正常,可以:
- 用CDK的测试模块模拟API Gateway请求
- 或者在测试环境部署后,发送真实HTTP请求验证端点响应
示例集成测试片段:
import { HttpApi, HttpMethod } from '@aws-cdk/aws-apigatewayv2'; import { HttpLambdaIntegration } from '@aws-cdk/aws-apigatewayv2-integrations'; import { Stack } from '@aws-cdk/core'; import { LambdaFunction } from '@aws-cdk/aws-lambda'; import fetch from 'node-fetch'; test('API Gateway端点返回正确响应', async () => { // 模拟栈和资源(和你的生产代码逻辑一致) const stack = new Stack(); const testLambda = new LambdaFunction(stack, 'TestLambda', { code: LambdaFunction.fromAsset('src/lambda'), handler: 'example.handler', environment: { STEP_FUNCTION_ARN: 'test-arn' } }); const httpApi = new HttpApi(stack, 'TestApi'); httpApi.addRoutes({ path: '/example', methods: [HttpMethod.POST], integration: new HttpLambdaIntegration('TestIntegration', testLambda) }); // 假设测试环境部署后的端点URL const endpoint = 'https://your-test-api-id.execute-api.region.amazonaws.com/example'; const response = await fetch(endpoint, { method: 'POST', body: JSON.stringify({ key: 'value' }) }); expect(response.status).toBe(200); const body = await response.text(); expect(body).toBe('Success!'); });
额外提示
- 测试里所有AWS服务调用一定要用模拟工具,别触发真实资源操作,避免不必要的费用和风险
- 测试时显式设置环境变量,防止
process.env.STEP_FUNCTION_ARN出现undefined报错 - 后续新增业务逻辑时,同步更新测试用例,覆盖边缘场景
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

