首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟AWS sqs调用进行单元测试

如何模拟AWS sqs调用进行单元测试
EN

Stack Overflow用户
提问于 2019-08-21 14:28:15
回答 2查看 17.4K关注 0票数 12

我在Node应用程序中使用AWS SQS queue,并且我必须为同样的应用程序编写单元测试用例。为此,我想模拟SQS函数调用sendMessage()那么,我应该怎么做呢?

我试过使用aws-sdk-mock但是在调用sendMessage(),则该函数正在尝试连接到队列URL。

测试文件

代码语言:javascript
复制
import AWSMock from 'aws-sdk-mock'
import sendMessage from '../api/sqs/producer'

describe.only('Test case for SQS SendMessage', () => {
  it('should return the UserEvent', async () => {
    AWSMock.mock('SQS', 'sendMessage', () => Promise.resolve('Success'))
    const res = await sendMessage('testURL', 'data')
    console.log('RES', res.response.data)
  })
})

生产者文件

代码语言:javascript
复制
const AWS = require('aws-sdk')

const sqs = new AWS.SQS({
  region: 'us-east-1'
})

const sendMessage = async (msg, queueUrl) => {
  try {
    const params = {
      MessageBody: JSON.stringify(msg),
      QueueUrl: queueUrl
    }
    const res = await sqs.sendMessage(params).promise()
    return res
  } catch (err) {
    console.log('Error:', `failed to send message ${err}`)
    throw new Error(err)
  }
}

export { sendMessage as default }

在上面的代码中,我期望Success中的返回值

资源

输出

代码语言:javascript
复制
FAIL  tests/sendMessage.test.js
  ● Console

    console.log api/sqs/producer/index.js:16
      Error: failed to send message UnknownEndpoint: Inaccessible host: `testurl'. This service may not b
e available in the `us-east-1' region.

  ● Test case for SQS SendMessage › should return the UserEvent

    UnknownEndpoint: Inaccessible host: `testurl'. This service may not be available in the `us-east-1' r
egion.
EN

回答 2

Stack Overflow用户

发布于 2019-09-24 13:15:47

这就是解决方案,你不需要aws-sdk-mock模块,您可以模拟aws-sdk一个人。

index.ts

代码语言:javascript
复制
import AWS from 'aws-sdk';

const sqs = new AWS.SQS({
  region: 'us-east-1'
});

const sendMessage = async (msg, queueUrl) => {
  try {
    const params = {
      MessageBody: JSON.stringify(msg),
      QueueUrl: queueUrl
    };
    const res = await sqs.sendMessage(params).promise();
    return res;
  } catch (err) {
    console.log('Error:', `failed to send message ${err}`);
    throw new Error(err);
  }
};

export { sendMessage as default };

index.spec.ts

代码语言:javascript
复制
import sendMessage from './';
import AWS from 'aws-sdk';

jest.mock('aws-sdk', () => {
  const SQSMocked = {
    sendMessage: jest.fn().mockReturnThis(),
    promise: jest.fn()
  };
  return {
    SQS: jest.fn(() => SQSMocked)
  };
});

const sqs = new AWS.SQS({
  region: 'us-east-1'
});

describe.only('Test case for SQS SendMessage', () => {
  beforeEach(() => {
    (sqs.sendMessage().promise as jest.MockedFunction).mockReset();
  });
  it('should return the UserEvent', async () => {
    expect(jest.isMockFunction(sqs.sendMessage)).toBeTruthy();
    expect(jest.isMockFunction(sqs.sendMessage().promise)).toBeTruthy();
    (sqs.sendMessage().promise as jest.MockedFunction).mockResolvedValueOnce('mocked data');
    const actualValue = await sendMessage('testURL', 'data');
    expect(actualValue).toEqual('mocked data');
    expect(sqs.sendMessage).toBeCalledWith({ MessageBody: '"testURL"', QueueUrl: 'data' });
    expect(sqs.sendMessage().promise).toBeCalledTimes(1);
  });

  it('should throw an error when send message error', async () => {
    const sendMessageErrorMessage = 'network error';
    (sqs.sendMessage().promise as jest.MockedFunction).mockRejectedValueOnce(sendMessageErrorMessage);
    await expect(sendMessage('testURL', 'data')).rejects.toThrowError(new Error(sendMessageErrorMessage));
    expect(sqs.sendMessage).toBeCalledWith({ MessageBody: '"testURL"', QueueUrl: 'data' });
    expect(sqs.sendMessage().promise).toBeCalledTimes(1);
  });
});

100%覆盖率的单元测试结果:

代码语言:javascript
复制
PASS  src/stackoverflow/57585620/index.spec.ts
  Test case for SQS SendMessage
    ✓ should return the UserEvent (7ms)
    ✓ should throw an error when send message error (6ms)

  console.log src/stackoverflow/57585620/index.ts:3137
    Error: failed to send message network error

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.453s, estimated 6s

完成的demo如下:

https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57585620

票数 24
EN

Stack Overflow用户

发布于 2021-02-26 04:41:51

如果您有一个静态的sqs测试消息(例如,在单元测试的情况下,由于某些不可避免的原因,您确实遇到了sqs ),您可以通过简单地对一个实际的SQS队列运行sendMessage来计算md5总和(在某些burner AWS帐户中快速创建一个,然后记录响应并在响应中md5sum MessageBody对象)。

在您的单元测试中,您可以简单地使用以下命令锁定SQS

代码语言:javascript
复制
const requestId = 'who';
    const messageId = 'wha';
    nock('https://sqs.eu-central-1.amazonaws.com')
        .post('/')
        .reply(
            200,
            `193816d2f70f3e15a09037a5fded52f6${messageId}${requestId}`,
        );

不要忘记更改您的区域,当然还有md5sum ;)

这个方法没有明显的伸缩性,除非你预先计算了messageBody的md5sum :)

也许它可以帮助一些使用静态单元测试消息的人快速修复。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57585620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档