测试异步 SQS sendMessage

Testing async SQS sendMessage

我有一个异步 lambda,它执行一个异步 SQS sendMessage 请求。 SQS队列是标准队列,不是FIFO,澄清一下。

这是一个代码示例(没有不相关的逻辑部分):

exports.functionHandler = async (event, context, callback) => {
    try {
        let parsedBody = JSON.parse(event.Records[0].body);
        let modifiedBody = await doStuff(parsedBody);

        let sqsPayload = {
            MessageBody: JSON.stringify(modifiedBody),
            QueueUrl: my-queue-url
        };

        await sqs.sendMessage(sqsPayload).promise();

        callback(null, utils.respondSuccess("Done"));
    } catch (err) {
        // Handle error

        callback(null, utils.respondError(err));
    }
};

const doStuff = async payload => {
    // Do stuff 
}

很简单。

现在的问题是:我正在尝试使用包 aws-sdk-mock 测试此功能。当 lambda 不是异步的并且 sendMessage 函数正在使用回调时,这就是我对 sendMessage 函数进行存根的方式:

it("an awesome title for my test", async () => {
    let payload = {
        Records: [
            // Data here
        ]
    };

    AWS.mock("SQS", "sendMessage", (param, callback) => {
        let response = {
            ResponseMetadata: {
                RequestId: "test-request-id"
            },
            MD5OfMessageBody: "a892e8d8589e97ca92fb70020f01c16c",
            MessageId: "test-message-id"
        };

        callback(null, response);
    });

    await app.functionHandler(payload, {}, (err, result) => {
        let parsedBody = JSON.parse(result.body);
        expect(parsedBody.message).to.be.equal("Done");
        // More stuff
    });

    AWS.restore();
});

如果我使用此测试,sendMessage 函数会抛出以下错误:

sendMessage returned an invalid MD5 response. Got "undefined", expecting "a892e8d8589e97ca92fb70020f01c16c".

我不确定如何异步测试 sendMessage。如果可以帮助我完成工作,我不介意采用不同的软件包。

有人能帮忙吗?

非常感谢

我没有使用过 aws-sdk-mock,但显然在您的模拟中您正在使用回调,而在 lambda 处理程序中它是一个异步调用。我使用 proxyquire 来模拟依赖项。这是一个例子:

functionHandler.js

不需要在 Lambda 运行时使用 callbackcontext Node8.10

let AWSSQS = require('aws-sdk/clients/sqs');
let sqs = new AWSSQS();

exports.functionHandler = async (event) => {

  // No need to use callback when Lambda runtime is 8.10.
  try {

    let parsedBody = JSON.parse(event.Records[0].body);
    let modifiedBody = await doStuff(parsedBody);

    let sqsPayload = {
      MessageBody: JSON.stringify(modifiedBody),
      QueueUrl: my-queue-url
    };

    await sqs.sendMessage(sqsPayload).promise();

    return utils.respondSuccess('Done');
  } catch (err) {
    throw utils.respondError(err);
  }
};

test.spec.js

几乎不言自明。您将依赖名称定义为 属性.

的对象
const proxyquire = require('proxyquire');

let app = require('path/to/function');

describe('SQS', () => {

  it("an awesome title for my test", async (done) => {

    const app = proxyquire(app, {
      'aws-sdk/clients/sqs': function() {
        this.sendMessage = (params) => {
          return {
            promise: () => {
              return Promise.resolve({
                ResponseMetadata: {
                  RequestId: 'test-request-id'
                },
                MD5OfMessageBody: 'a892e8d8589e97ca92fb70020f01c16c',
                MessageId: 'test-message-id'
              });
            }
          }
        }
      }
    });

    let payload = {
      Records: [
        // Data here
      ]
    };

    const data = await app.functionHandler(payload);
    let parsedBody = JSON.parse(data.body);
    expect(parsedBody.message).to.be.equal("Done");
    done();
  });
});