使用aws-sdk-mock对DocumentClient的承诺支持进行模拟

时间:2017-02-24 16:29:34

标签: node.js aws-sdk aws-sdk-mock

我尝试使用aws-sdk-mock的承诺支持来编写单元测试。我正在使用DocumentClient。

我的代码如下所示:

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);
});

我的模拟和单元测试看起来像这样:

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();
});

运行我的单元测试,不返回我的测试值,它实际上绕过我的模拟,并直接调用dynamoDb。我究竟做错了什么?我怎样才能正确设置模拟器?

5 个答案:

答案 0 :(得分:9)

您的代码中不清楚,但aws-sdk-mock有此注释

  

注意:需要在正在测试的函数内初始化AWS服务,以便模拟SDK方法

所以以下内容不会正确模拟

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 
}

但这将

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 
}

点击此处https://github.com/dwyl/aws-sdk-mock#how-usage

答案 1 :(得分:5)

答案可能为时已晚,但是我遇到了同样的问题,并且偶然发现了这个问题。经过几次尝试,我找到了一个不涉及aws-sdk-mock而仅涉及普通的Sinon的解决方案,并且希望共享该解决方案对其他人有所帮助。请注意,DynamoDB客户端是在lambda之外创建的。

lambda本身如下所示:

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.' });
    }
};

对此lambda的测试是:

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();
    });
});

我喜欢使用Sinon的沙箱来存根很多不同的DynamoDB方法,并在一个restore()中清理所有内容。

答案 2 :(得分:0)

与该问题有关的一些问题,扩大了wyu的解决方案-我也面临类似的问题-对我来说,以下不适用于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();
};

在什么地方起作用

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();
};

答案 3 :(得分:0)

sinonproxyquire可用于模拟dynamodb客户端。

它支持基于回调的调用和基于异步/等待的调用。

请参阅此链接以获取全部详细信息 https://yottabrain.org/nodejs/nodejs-unit-test-dynamodb/

答案 4 :(得分:0)

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

let sns = new AWS.SNS(.....)
相关问题