使用承诺的 Lambda 的 sinon 存根
sinon stub for Lambda using promises
我刚开始使用 sinon,我在排除 DynamoDB 调用方面取得了一些初步成功:
sandbox = sinon.createSandbox()
update_stub = sandbox.stub(AWS.DynamoDB.DocumentClient.prototype, 'update').returns({
promise: () => Promise.resolve(update_meeting_result)
})
效果很好。
但我还需要存根 Lambda,但同样的方法不起作用:
lambda_stub = sandbox.stub(AWS.Lambda.prototype, 'invoke').returns({
promise: () => Promise.resolve({lambda_invoke_result}) //
})
有了这个,我得到了错误:Cannot stub non-existent property invoke
。
示例实现:
const AWS = require("aws-sdk")
AWS.config.update({region: 'us-west-2'})
const dynamodb = new AWS.DynamoDB.DocumentClient()
const lambda = new AWS.Lambda()
// lambda function handler
exports.handler = async (event) => {
let result = await dynamodb.get({/* some get config */}).promise()
// do stuff ...
// kick off next lambda
await lambda.invoke({/* lambda config */}).promise()
return {"status": "ok"} // or something
}
单元测试解决方案如下:
index.js
:
const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-west-2' });
const dynamodb = new AWS.DynamoDB.DocumentClient();
const lambda = new AWS.Lambda();
exports.handler = async (event) => {
let result = await dynamodb.get({}).promise();
await lambda.invoke({}).promise();
return { status: 'ok' };
};
index.test.js
:
const sinon = require('sinon');
const AWS = require('aws-sdk');
describe('61516053', () => {
afterEach(() => {
sinon.restore();
});
it('should pass', async () => {
const mLambda = { invoke: sinon.stub().returnsThis(), promise: sinon.stub() };
sinon.stub(AWS, 'Lambda').callsFake(() => mLambda);
const mDocumentClient = { get: sinon.stub().returnsThis(), promise: sinon.stub() };
sinon.stub(AWS.DynamoDB, 'DocumentClient').callsFake(() => mDocumentClient);
sinon.stub(AWS.config, 'update');
const { handler } = require('./');
await handler();
sinon.assert.calledWith(AWS.config.update, { region: 'us-west-2' });
sinon.assert.calledOnce(AWS.DynamoDB.DocumentClient);
sinon.assert.calledOnce(AWS.Lambda);
sinon.assert.calledWith(mLambda.invoke, {});
sinon.assert.calledOnce(mLambda.promise);
sinon.assert.calledWith(mDocumentClient.get, {});
sinon.assert.calledOnce(mDocumentClient.promise);
});
});
100% 覆盖率的单元测试结果:
61516053
✓ should pass (907ms)
1 passing (915ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
我刚开始使用 sinon,我在排除 DynamoDB 调用方面取得了一些初步成功:
sandbox = sinon.createSandbox()
update_stub = sandbox.stub(AWS.DynamoDB.DocumentClient.prototype, 'update').returns({
promise: () => Promise.resolve(update_meeting_result)
})
效果很好。
但我还需要存根 Lambda,但同样的方法不起作用:
lambda_stub = sandbox.stub(AWS.Lambda.prototype, 'invoke').returns({
promise: () => Promise.resolve({lambda_invoke_result}) //
})
有了这个,我得到了错误:Cannot stub non-existent property invoke
。
示例实现:
const AWS = require("aws-sdk")
AWS.config.update({region: 'us-west-2'})
const dynamodb = new AWS.DynamoDB.DocumentClient()
const lambda = new AWS.Lambda()
// lambda function handler
exports.handler = async (event) => {
let result = await dynamodb.get({/* some get config */}).promise()
// do stuff ...
// kick off next lambda
await lambda.invoke({/* lambda config */}).promise()
return {"status": "ok"} // or something
}
单元测试解决方案如下:
index.js
:
const AWS = require('aws-sdk');
AWS.config.update({ region: 'us-west-2' });
const dynamodb = new AWS.DynamoDB.DocumentClient();
const lambda = new AWS.Lambda();
exports.handler = async (event) => {
let result = await dynamodb.get({}).promise();
await lambda.invoke({}).promise();
return { status: 'ok' };
};
index.test.js
:
const sinon = require('sinon');
const AWS = require('aws-sdk');
describe('61516053', () => {
afterEach(() => {
sinon.restore();
});
it('should pass', async () => {
const mLambda = { invoke: sinon.stub().returnsThis(), promise: sinon.stub() };
sinon.stub(AWS, 'Lambda').callsFake(() => mLambda);
const mDocumentClient = { get: sinon.stub().returnsThis(), promise: sinon.stub() };
sinon.stub(AWS.DynamoDB, 'DocumentClient').callsFake(() => mDocumentClient);
sinon.stub(AWS.config, 'update');
const { handler } = require('./');
await handler();
sinon.assert.calledWith(AWS.config.update, { region: 'us-west-2' });
sinon.assert.calledOnce(AWS.DynamoDB.DocumentClient);
sinon.assert.calledOnce(AWS.Lambda);
sinon.assert.calledWith(mLambda.invoke, {});
sinon.assert.calledOnce(mLambda.promise);
sinon.assert.calledWith(mDocumentClient.get, {});
sinon.assert.calledOnce(mDocumentClient.promise);
});
});
100% 覆盖率的单元测试结果:
61516053
✓ should pass (907ms)
1 passing (915ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------