Чтобы издеваться над AWS SES с Sinon - PullRequest
2 голосов
/ 22 марта 2019

Я пытаюсь издеваться над SES с Sinon, но сталкиваюсь с ошибкой ниже.Пробовал с помощью aws-sdk-mock, но это не работает.

Error: TypeError: Cannot stub non-existent own property sendEmail

Фрагмент кода тестового класса:

import * as AWS from 'aws-sdk';

const sandbox = sinon.createSandbox();
sandbox.stub(AWS.SES, 'sendEmail').returns({promise: () => true});

Фактический класс:

import * as AWS from 'aws-sdk';
import * as _ from 'lodash';    

export async function sendAlertMailOnFailure(status:any)
{   
    // load AWS SES
    var ses = new AWS.SES();   
    const params = {
        Destination: {
          ToAddresses: <to_address>
        },
        Message: {...},    
        Source: <sender_address>
      }
      ses.sendEmail(params, (err, data) => {
        if (err) {
          log.error("Error sending mail::");
          log.error(err, err.stack);
        }
      })
}

Isесть ли способ издеваться над SES с помощью Sinon или с помощью aws-sdk-mock?

Ответы [ 4 ]

1 голос
/ 22 марта 2019

Вам нужно использовать prototype в AWS, чтобы заглушить это:

import AWS from 'aws-sdk';

const sandbox = sinon.createSandbox();
sandbox.stub(AWS.prototype, 'SES').returns({
  sendEmail: () => {
    return true;
  }
});
0 голосов
/ 17 июня 2019

Мой ответ здесь не является прямым решением для SES, но является рабочим решением, которое я использую для насмешек DynamoDB.DocumentClient и SQS.Возможно, вы можете адаптировать мой рабочий пример для SES и других aws-sdk клиентов в своих модульных тестах.

Я просто часами пытался заставить работать AWS SQS mocking, без обращения кaws-sdk-mock требование импорта aws-sdk клиентов внутри функции.

Насмешка над AWS.DynamoDB.DocumentClient была довольно простой, но насмешка AWS.SQS приводила меня в тупик, пока я не наткнулся на предложение использовать rewire .

Моя лямбда перемещает плохие сообщения в SQS FailQueue (вместо того, чтобы позволить лямбде-неудаче завершить работу и вернуть сообщение в обычную очередь для повторных попыток, а затем DeadLetterQueue после maxRetries).В модульных тестах необходимо было смоделировать следующие методы SQS:

  • SQS.getQueueUrl
  • SQS.sendMessage
  • SQS.deleteMessage

Я постараюсь сделать этот пример кода как можно более кратким, в то же время включив все соответствующие части:

Фрагмент моей лямбда-версии AWS (index.js):

const AWS = require('aws-sdk');
AWS.config.update({region:'eu-west-1'});
const docClient = new AWS.DynamoDB.DocumentClient();
const sqs = new AWS.SQS({ apiVersion: '2012-11-05' });
// ...snip

Сокращенные записи событий лямбды (event.json)

{
    "valid": {
        "Records": [{
            "messageId": "c292410d-3b27-49ae-8e1f-0eb155f0710b",
            "receiptHandle": "AQEBz5JUoLYsn4dstTAxP7/IF9+T1S994n3FLkMvMmAh1Ut/Elpc0tbNZSaCPYDvP+mBBecVWmAM88SgW7iI8T65Blz3cXshP3keWzCgLCnmkwGvDHBYFVccm93yuMe0i5W02jX0s1LJuNVYI1aVtyz19IbzlVksp+z2RxAX6zMhcTy3VzusIZ6aDORW6yYppIYtKuB2G4Ftf8SE4XPzXo5RCdYirja1aMuh9DluEtSIW+lgDQcHbhIZeJx0eC09KQGJSF2uKk2BqTGvQrknw0EvjNEl6Jv56lWKyFT78K3TLBy2XdGFKQTsSALBNtlwFd8ZzcJoMaUFpbJVkzuLDST1y4nKQi7MK58JMsZ4ujZJnYvKFvgtc6YfWgsEuV0QSL9U5FradtXg4EnaBOnGVTFrbE18DoEuvUUiO7ZQPO9auS4=",
            "body": "{ \"key1\": \"value 1\", \"key2\": \"value 2\", \"key3\": \"value 3\", \"key4\": \"value 4\", \"key5\": \"value 5\" }",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1536763724607",
                "SenderId": "AROAJAAXYIAN46PWMV46S:steve.goossens@bbc.co.uk",
                "ApproximateFirstReceiveTimestamp": "1536763724618"
            },
            "messageAttributes": {},
            "md5OfBody": "e5b16f3a468e6547785a3454cfb33293",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:eu-west-1:123456789012:sqs-queue-name",
            "awsRegion": "eu-west-1"
        }]
    }
}

Сокращенный файл модульного теста (test / index.test.js):

const AWS = require('aws-sdk');
const expect = require('chai').expect;
const LamdbaTester = require('lambda-tester');
const rewire = require('rewire');
const sinon = require('sinon');

const event = require('./event');
const lambda = rewire('../index');

let sinonSandbox;

function mockGoodSqsMove() {
    const promiseStubSqs = sinonSandbox.stub().resolves({});
    const sqsMock = {
        getQueueUrl: () => ({ promise: sinonSandbox.stub().resolves({ QueueUrl: 'queue-url' }) }),
        sendMessage: () => ({ promise: promiseStubSqs }),
        deleteMessage: () => ({ promise: promiseStubSqs })
    }
    lambda.__set__('sqs', sqsMock);
}

describe('handler', function () {
    beforeEach(() => {
        sinonSandbox = sinon.createSandbox();
    });

    afterEach(() => {
        sinonSandbox.restore();
    });

    describe('when SQS message is in dedupe cache', function () {
        beforeEach(() => {
            // mock SQS
            mockGoodSqsMove();
            // mock DynamoDBClient
            const promiseStub = sinonSandbox.stub().resolves({'Item': 'something'});
            sinonSandbox.stub(AWS.DynamoDB.DocumentClient.prototype, 'get').returns({ promise: promiseStub });
        });

        it('should return an error for a duplicate message', function () {
            return LamdbaTester(lambda.handler)
                .event(event.valid)
                .expectReject((err, additional) => {
                    expect(err).to.have.property('message', 'Duplicate message: {"Item":"something"}');
                });
        });
    });
});
0 голосов
/ 14 мая 2019

Использование require & без использования прототипа.Это работает для меня дразнить DynamoDB.

const aws = require('aws-sdk');
const sinon = require('sinon');

const sandbox = sinon.createSandbox();

this.awsStub = sandbox.stub(aws, 'DynamoDB').returns({
  query: function() {
    return {
      promise: function() {
        return {
          Items: []
        };
      }
    };
  }
});

Пакеты :

"aws-sdk": "^ 2.453.0"

"sinon": "^ 7.3.2"

0 голосов
/ 22 марта 2019

Ошибка указывает на то, что AWS импортируется как undefined.

Возможно, ваш компилятор ES6 не поворачивает эту строку автоматически:

import AWS from 'aws-sdk';

... в импорт всего в aws-sdk в AWS.

Измените это на:

import * as AWS from 'aws-sdk';

... и это может решить проблему.


(Отказ от ответственности: я не могу воспроизвести ошибку в моей среде, которая компилируется с Babel v7 и автоматически обрабатывает любой подход)

...