web-dev-qa-db-ja.com

DocumentClientでのaws-sdk-mockのpromiseサポートを使用したモック

Aws-sdk-mockのpromiseサポートを使用して単体テストを作成しようとしています。 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が呼び出されます。何が悪いのですか?モックを適切に設定するにはどうすればよいですか?

10
JAck28

コードからは不明ですが、aws-sdk-mockにこのメモがあります

注意:SDKメソッドをモックするには、テスト対象の関数内でAWSサービスを初期化する必要があります

したがって、以下は正しくモックされません

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

14
wyu

答えを出すには遅すぎるかもしれませんが、私は同じ問題を抱えていて、私はこの質問に出くわしました。数回試した後、_aws-sdk-mock_を使用せず、単純なSinonのみを使用するソリューションを見つけました。それを共有すると、他の人の役に立つことを願っています。 DynamoDBクライアントはラムダの外部で作成されることに注意してください。

ラムダ自体は次のようになります。

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

そして、このラムダのテストは:

_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()ですべてをクリーンアップできるようにしたいと思っています。

6

sinonおよびproxyquireを使用して、dynamodbクライアントをモックできます。

コールバックベースと非同期/待機ベースの両方の呼び出しをサポートしています。

詳細については、このリンクを参照してください https://yottabrain.org/nodejs/nodejs-unit-test-dynamodb/

0
yottabrain

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