简体   繁体   中英

Mocking using aws-sdk-mock's promise support with DocumentClient

I'm trying to write a unit test using aws-sdk-mock's promise support. I'm using DocumentClient.

My code looks like this:

const docClient = new AWS.DynamoDB.DocumentClient();

const getItemPromise = docClient.get(params).promise();
   return getItemPromise.then((data) => {
   console.log('Success');
   return data;
}).catch((err) => {
   console.log(err);
});

My mock and unit test looks like this:

const AWS = require('aws-sdk-mock');
AWS.Promise = Promise.Promise;

AWS.mock('DynamoDB.DocumentClient', 'get', function (params, callback)
{
   callback(null, { Item: { Key: 'test value } });
});

dynamoStore.getItems('tableName', 'idName', 'id').then((actualResponse) => {
  // assertions
  done();
});

Runnning my unit test, does not return my test value, it actually bypasses my mock, and calls calls dynamoDb directly. What am I doing wrong? How can I get my mock set up properly?

It's unclear from your code but aws-sdk-mock has this note

NB: The AWS Service needs to be initialised inside the function being tested in order for the SDK method to be mocked

so the following will not mock correctly

var AWS      = require('aws-sdk');
var sns      = AWS.SNS();
var dynamoDb = AWS.DynamoDB();

exports.handler = function(event, context) {
  // do something with the services e.g. sns.publish 
}

but this will

var AWS = require('aws-sdk');

exports.handler = function(event, context) {
  var sns      = AWS.SNS();
  var dynamoDb = AWS.DynamoDB();
  // do something with the services e.g. sns.publish 
}

see more here https://github.com/dwyl/aws-sdk-mock#how-usage

It might be too late for an answer, but I had the same problem and I stumbled upon this question. After a few tries I found a solution that doesn't involve aws-sdk-mock but only plain Sinon, and I hope that sharing it would help someone else. Note that the DynamoDB client is create outside the lambda.

The lambda itself looks like this:

const dynamoDB = new DynamoDB.DocumentClient();

exports.get = async event => {
    const params = {
        TableName: 'Tasks',
        Key: {
            id: event.pathParameters.id
        }
    };

    const result = await dynamoDB.get(params).promise();
    if (result.Item) {
        return success(result.Item);
    } else {
        return failure({ error: 'Task not found.' });
    }
};

And the test for this lambda is:

const sandbox = sinon.createSandbox();

describe('Task', () => {

    beforeAll(() => {
        const result = { Item: { id: '1', name: 'Go to gym'}};
        sandbox.stub(DynamoDB.DocumentClient.prototype, 'get').returns({promise: () => result});
    });

    afterAll(() => {
        sandbox.restore();
    });

    it('gets a task from the DB', async () => {
        // Act
        const response = await task.get(getStub);
        // Assert
        expect(response.statusCode).toEqual(200);
        expect(response.body).toMatchSnapshot();
    });
});

I like to use Sinon's sandbox to be able to stub a whole lot of different DynamoDB methods and clean up everything in a single restore() .

sinon and proxyquire can be used to mock the dynamodb client.

It supports both callback based and async/await based calls.

Refer this link for full details https://yottabrain.org/nodejs/nodejs-unit-test-dynamodb/

Somewhat related to the question, expanding wyu's solution - i too faced similar issue - for me, below didn't work with aws-sdk-mock

const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
let call = function (action, params) {    
    const dynamoDb = new AWS.DynamoDB.DocumentClient();

    return dynamoDb[action](params).promise();
};

where as this worked

let call = function (action, params) {
    const AWS = require('aws-sdk');
    AWS.config.update({region: 'us-east-1'});
    const dynamoDb = new AWS.DynamoDB.DocumentClient();

    return dynamoDb[action](params).promise();
};

我遇到了完全相同的模拟失败问题,但在遵循上述用户的建议后解决了该问题,方法是在函数内移动以下行而不是在外部定义:

let sns = new AWS.SNS(.....)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM