Open nitrocode opened 6 years ago
You have to call AWSMock.mock BEFORE instantiating the client object. So you cannot do const dynamodb = new AWS.DynamoDB();
and then mock it afterwards.
Thanks, this worked for me. I edited the above post. Does my setup make sense from the dev side and the test side now? Is there a better way to restructure the code to make testing / mocking easier?
Im having the same issue, its giving me lambda.invoke(...).promise is not a function
, im doing the .mock() in the beforeEach func and restoring it in the afterEach, like so:
AWS.mock('Lambda', 'invoke', (params, callback) => {
const awsResponse = {
LogResult:'some-data',
Payload:'{\'contentType\':\'text/plain\',\'message\':\'some-other-data\',\'status\':200}',
StatusCode:200
};
callback(null, awsResponse);
})
lambda.invoke({
FunctionName: functionName,
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: Buffer.from(JSON.stringify(params))
}).promise();
Do I need to change the way I call the callback function or wrap it in a promise or something in those lines?
@CarlosV89 did you ever find a resolution to this? I'm having the same problem.
Here an example that I used in using lambda invoke ,
I'm creating a function called callSync() where the callSync() function is actually invoke another lambda function:
exports.callSync = async function(params) {
const lambda = new AWS.lambda({
region: 'ap-southeast-1';
});
const invokeParam = {
FunctionName: params.serviceName,
InvocationType: params.invokeType,
Payload: params.lambdaPayload,
Qualifier: params.alias
};
await lambda.invoke(invokeParam).promise()
.then(res => res.StatusCode)
.catch((error) => {
throw new Error(error.message);
});
}
then in my unit-testing, I'm using ava js anyway
const test = require('ava');
const sinon = require('sinon');
const AWS = require('aws-sdk-mock');
const callSync = require('./callSync');
test.serial('callSync invoke succesfully', async function(t) {
const invokeReplace = function () {
return new Promise(((resolve) => {
resolve({ StatusCode: 200 });
}));
};
AWS.mock('Lambda', 'invoke', invokeReplace());
await callSync('RequestResponse', 'test-service', 'updateTest', {}).then(() => t.pass('sukses invoke callSync'));
});
test.serial('callSync will throw error on failed invocation, async function(t) {
const invokeReplace = function () {
return new Promise(((resolve, reject) => {
reject(new Error('it is somewhat error'));
}));
};
AWS.mock('Lambda', 'invoke', invokeReplace());
await callSync('RequestResponse', 'test-service', 'updateTest', {}).catch((error) => {
t.is(error.message, 'it is somewhat error');
});
});
test.beforeEach('Initialize New Sandbox Before Each Test', (t) => {
t.context.sandbox = sinon.sandbox.create().usingPromise(Promise.Promise);
});
test.afterEach.always(
'Restore Sandbox and Configuration After Each Test',
(t) => {
t.context.sandbox.restore();
AWS.restore();
}
);
The simplest thing to do is just test if you've been passed a callback and if not return a promise from the mock.
AWSMock.mock('StepFunctions', 'listStateMachines', (p: ListStateMachinesInput, callback: Function) => {
let response: ListStateMachinesOutput = {
stateMachines: [
{
stateMachineArn: 'arn:aws:states:us-east-1:123456789012:stateMachine:my-state-machine',
name: 'my-state-machine',
type: 'STANDARD',
creationDate: moment().toDate()
},
{
stateMachineArn: 'arn:aws:states:us-east-1:123456789012:stateMachine:my-second-machine',
name: 'my-second-machine',
type: 'STANDARD',
creationDate: moment().toDate()
}
]
};
if (!callback) {
return new Promise((resolve => {
resolve(response);
}));
} else {
return callback(null, response);
}
});
Here's my code:
function getItem(params) { return dynamodb.getItem(params).promise(); // return dynamodb.getItem(params).promise().then(response => response.Item); }
module.exports = { // ... getItem, }
let pool; let dynamodb;
function getItem(params) { return dynamodb.getItem(params).promise(); }
function getItem2(params) { return dynamodb.getItem(params).promise().then(response => response.Item); }
describe('Test getItem', function () { it('should return what we put in', async function () { AWSMock.mock('DynamoDB', 'getItem', function(params, callback) { callback(null, { response: { Item: { data: { S: 'data' } } } }); });
}); });