我在Node应用程序中使用AWS SQS queue,并且我必须为同样的应用程序编写单元测试用例。为此,我想模拟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中的返回值
资源
输出
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.发布于 2019-09-24 13:15:47
这就是解决方案,你不需要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).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%覆盖率的单元测试结果:
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
发布于 2021-02-26 04:41:51
如果您有一个静态的sqs测试消息(例如,在单元测试的情况下,由于某些不可避免的原因,您确实遇到了sqs ),您可以通过简单地对一个实际的SQS队列运行sendMessage来计算md5总和(在某些burner AWS帐户中快速创建一个,然后记录响应并在响应中md5sum MessageBody对象)。
在您的单元测试中,您可以简单地使用以下命令锁定SQS
const requestId = 'who';
const messageId = 'wha';
nock('https://sqs.eu-central-1.amazonaws.com')
.post('/')
.reply(
200,
`193816d2f70f3e15a09037a5fded52f6${messageId}${requestId}`,
);不要忘记更改您的区域,当然还有md5sum ;)
这个方法没有明显的伸缩性,除非你预先计算了messageBody的md5sum :)
也许它可以帮助一些使用静态单元测试消息的人快速修复。
https://stackoverflow.com/questions/57585620
复制相似问题