【问题标题】:Testing async SQS sendMessage测试异步 SQS sendMessage
【发布时间】:2019-06-12 23:37:41
【问题描述】:

我有一个异步 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。如果它有助于我完成工作,我不介意采用不同的包。

谁能帮忙?

非常感谢

【问题讨论】:

    标签: javascript node.js aws-lambda amazon-sqs aws-sdk-mock


    【解决方案1】:

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

    functionHandler.js

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

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

    【讨论】:

    • 感谢有关上下文/回调的提示。实现 proxyquire 后,我仍然得到同样的错误。我也尝试过用 sinon 解决 promise,但是一样
    • 我意识到我的代码有一些拼写错误。模拟方法应该是this.sendMessage。我也使用 rewire 而不是 path/to/function 的要求。
    • 我已经修复了这些但没有工作,但现在我设法让它工作了。我的问题是对 SQS 的要求不同(我需要 sdk 并从 sdk 实例化 sqs)。可能我在代理查询中对它的适应很差。像您所做的那样直接要求 sqs 并在 proxyquire 中使用 aws-sdk/clients/sqs 解决了我的问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-12-17
    • 2014-09-04
    • 1970-01-01
    • 2021-08-31
    • 2019-11-22
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多