unit-testing - AWS Mock 无法模拟 Lambda 调用()
问题描述
我试图在我的 Jest 中模拟一个 Lambda.invoke() 调用。但是,模拟调用不起作用,而是执行了真正的 invoke() 方法,该方法导致not authorized to perform: lambda:InvokeFunction
. 我无法找出问题所在,因为我在模拟 DynamoDB.DocumentClient 时也做了同样的事情,而且它没有任何问题。
笑话文件:
describe('Mock Lambda', () => {
beforeAll(async () => {
AWSMock.mock('Lambda', 'invoke', (params, callback) => {
if (params.FunctionName === 'MyLambaInvocation') {
callback(null, { status: 200, data: { code: '0', message: 'Successful' }
}
});
const result = await (myTest.handler(event, context(), null) as Promise<APIGatewayProxyResult>);
});
打字稿文件:
import { Lambda } from 'aws-sdk';
export function invokeLambda(eventObject) {
return new Promise<any>((resolve, reject) => {
const lambdaConfig = {
region: 'ap-southeast-1',
endpoint: process.env.IS_OFFLINE ? 'http://localhost:8080' : undefined
};
const lambda = new Lambda(lambdaConfig);
const params = {
FunctionName: 'MyLambaInvocation',
Payload: JSON.stringify(eventObject)
};
lambda.invoke(params, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
解决方案
这是一个仅使用 jestjs 模拟的示例。
index.ts
:
import { Lambda } from 'aws-sdk';
export function invokeLambda(eventObject) {
return new Promise<any>((resolve, reject) => {
const lambdaConfig = {
region: 'ap-southeast-1',
endpoint: process.env.IS_OFFLINE ? 'http://localhost:8080' : undefined,
};
const lambda = new Lambda(lambdaConfig);
const params = {
FunctionName: 'MyLambaInvocation',
Payload: JSON.stringify(eventObject),
};
lambda.invoke(params, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
index.test.ts
:
import { invokeLambda } from './';
import { Lambda as LambdaMock } from 'aws-sdk';
jest.mock('aws-sdk', () => {
const mLambda = { invoke: jest.fn() };
return { Lambda: jest.fn(() => mLambda) };
});
describe('Mock Lambda', () => {
it('should invoke lambda', async () => {
const mLambda = new LambdaMock();
const mResult = {};
(mLambda.invoke as jest.Mocked<any>).mockImplementationOnce((params, callback) => {
callback(null, mResult);
});
const actual = await invokeLambda({});
expect(actual).toEqual({});
expect(LambdaMock).toBeCalledWith({ region: 'ap-southeast-1', endpoint: undefined });
expect(mLambda.invoke).toBeCalledWith(
{
FunctionName: 'MyLambaInvocation',
Payload: JSON.stringify({}),
},
expect.any(Function),
);
});
it('should handle error if invoke failure', async () => {
const mLambda = new LambdaMock();
const mError = new Error('network');
(mLambda.invoke as jest.Mocked<any>).mockImplementationOnce((params, callback) => {
callback(mError);
});
await expect(invokeLambda({})).rejects.toThrow('network');
expect(LambdaMock).toBeCalledWith({ region: 'ap-southeast-1', endpoint: undefined });
expect(mLambda.invoke).toBeCalledWith(
{
FunctionName: 'MyLambaInvocation',
Payload: JSON.stringify({}),
},
expect.any(Function),
);
});
});
带有覆盖率报告的单元测试结果:
PASS stackoverflow/60753252/index.test.ts
Mock Lambda
✓ should invoke lambda (8ms)
✓ should handle error if invoke failure (3ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 75 | 100 | 100 |
index.ts | 100 | 75 | 100 | 100 | 7
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 4.054s, estimated 11s
源代码:https ://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60753252
推荐阅读
- batch-file - 在 Windows 上安全地杀死 java 进程
- python - Pyparsing 无法解析多个规则
- php - 有没有比使用 App\Entity\ as E 更好的方法
- javascript - 如何在单击向上和向下箭头按钮时上下移动选定/多选数组元素?
- html - 如何在 rails strong params 中包含 HTML 输入?
- c# - 如何在 DataGridView 的单元格中搜索精确值?
- dynamic-programming - 硬币变化:重叠的子问题是什么?
- java - 为什么 HBase 使用 NavigableMap
存储细胞? | - javascript - 在沙盒 iframe 中使用常见的 JS 库
- javascript - 单击按钮时JS .click()不起作用