16

我正在尝试使用 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。我究竟做错了什么?如何正确设置我的模拟?

4

5 回答 5

18

从您的代码中不清楚,但 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

于 2017-04-03T16:32:42.517 回答
16

答案可能为时已晚,但我遇到了同样的问题,我偶然发现了这个问题。经过几次尝试,我找到了一个不涉及aws-sdk-mock但只涉及普通诗农的解决方案,我希望分享它可以帮助其他人。请注意,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().

于 2018-12-30T19:02:54.240 回答
1

sinon并可proxyquire用于模拟 dynamodb 客户端。

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

有关完整详细信息,请参阅此链接 https://yottabrain.org/nodejs/nodejs-unit-test-dynamodb/

于 2019-05-10T09:09:36.087 回答
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();
};
于 2018-08-27T11:15:43.977 回答
0

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

let sns = new AWS.SNS(.....)
于 2020-06-07T16:09:59.620 回答