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

2024-04-20

我在 Node 应用程序中使用 AWS SQS 队列,并且必须为其编写单元测试用例。为此,我想模拟 SQS 函数调用sendMessage()在测试文件中,我应该做什么?

我尝试过使用aws-sdk-mock但在拨打电话时sendMessage(),该函数正在尝试连接到队列 URL。

测试文件

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

制作人文件

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作为返回值res

Output

 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.

这是解决方案,您不需要aws-sdk-mock模块,你可以模拟aws-sdk靠你自己。

index.ts:

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:

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<any>).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<any>).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<any>).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%覆盖率的单元测试结果:

 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

这是完成的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57585620 https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57585620

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何模拟 AWS sqs 调用进行单元测试 的相关文章

随机推荐