如何在 Jest Node JS 中测试 AWS 内置方法中使用的 .promise() 方法
How to test .promise() methods used in AWS built in methods in jest Node JS
我想对此进行完整的单元测试,下面给出了我的函数的代码
function.js
async function sesSendEmail(message) {
var ses = new aws.SES({ apiVersion: "2020-12-01" });
var params = {
Source: "abc@gmail.com",
Template: "deviceUsageStatisticsEmailTemplate",
Destination: {
ToAddresses: ["xyz@gmail.com"]
},
TemplateData: message,
}
try {
let res = await ses.sendTemplatedEmail(params).promise()
console.log(res)
}
catch (err) {
console.log(err)
}
到目前为止我在测试中尝试过的内容:
function.test.js
test('should send templated email success', async () => {
jest.spyOn(console, 'log');
const mData = {};
ses.sendTemplatedEmail.mockImplementationOnce(async (params,callback) => {
callback(null,mData)
});
const message = 'mock message';
await index.sesSendEmail(message);
expect(aws.SES).toBeCalledWith({ apiVersion: '2020-12-01' });
expect(ses.sendTemplatedEmail).toBeCalledWith(
{
Source: 'abc@gmail.com',
Template: 'deviceUsageStatisticsEmailTemplate',
Destination: {
ToAddresses: ['xyz@gmail.com'],
},
TemplateData: message,
},
);
await expect(console.log).toBeCalledWith(mData);
});
test('should handle error', () => {
const arb = "network error"
ses.sendTemplatedEmail = jest.fn().mockImplementation(() => {
throw new Error(arb);
})
const message = 'mock message'
expect(() => { index.sesSendEmail(message) }).toThrow(arb);
});
});
问题:
报错
expect(jest.fn()).toBeCalledWith(...expected)
- Expected
+ Received
- Object {}
+ [TypeError: ses.sendTemplatedEmail(...).promise is not a function],
我尝试了模拟实现的变体,但无济于事。非常感谢 help/suggestion:)
更新
尝试要求 aws-sdk-mock
aws.mock('ses','sendTemplatedEmail',function(callback){callback(null,mData)})
但仍然出现错误
TypeError: Cannot stub non-existent own property ses
我会说模拟 aws sdk 本身并按照您通常的方式测试您的方法。一旦这样的库是 aws-sdk-mock
(https://www.npmjs.com/package/aws-sdk-mock)
像这样
const sinon = require("sinon");
const AWS = require("aws-sdk-mock");
test("should send templated email success", async () => {
const sendEmailStub = sinon.stub().resolves("resolved");
AWS.mock("SES", "sendTemplatedEmail", sendEmailStub);
const response = await sesSendEmail("{\"hi\": \"bye\"}");
expect(sendEmailStub.calledOnce).toEqual(true);
expect(sendEmailStub.calledWith(
{
"Source": "abc@gmail.com",
"Template": "deviceUsageStatisticsEmailTemplate",
"Destination": {
"ToAddresses": ["xyz@gmail.com"]
},
"TemplateData": "{\"hi\": \"bye\"}"
})).toEqual(true);
expect(response).toEqual("resolved");
AWS.restore();
});
test("should send templated email failure", async () => {
const sendEmailStubError = sinon.stub().rejects("rejected");
AWS.mock("SES", "sendTemplatedEmail", sendEmailStubError);
const response = await sesSendEmail("{\"hi\": \"bye\"}");
expect(sendEmailStubError.calledOnce).toEqual(true);
expect(sendEmailStubError.calledWith(
{
"Source": "abc@gmail.com",
"Template": "deviceUsageStatisticsEmailTemplate",
"Destination": {
"ToAddresses": ["xyz@gmail.com"]
},
"TemplateData": "{\"hi\": \"bye\"}"
})).toEqual(true);
expect(response.name).toEqual("rejected");
AWS.restore();
});
确保从您的原始方法返回响应和错误。
TypeError: ses.sendTemplatedEmail(...).promise is not a function
表示它期望调用 ses.sendTemplatedEmail()
的结果是一个对象,该对象具有名为 promise
.
的函数 属性
要解决此问题,您将需要 return 模拟实现中的对象具有预期的 promise
属性。您还需要从模拟实现中删除 async
关键字,因为那样会 return 一个 Promise 对象,而不是具有 promise
属性.
的预期对象
这里是一个示例,它也 returns 来自 .promise()
的 Promise 对象,正如 sendTemplatedEmail.promise()
的生产实施所期望的那样:
ses.sendTemplatedEmail.mockImplementationOnce((params,callback) => ({
promise: () => Promise.resolve(callback(null,mData)),
}));
我想对此进行完整的单元测试,下面给出了我的函数的代码
function.js
async function sesSendEmail(message) {
var ses = new aws.SES({ apiVersion: "2020-12-01" });
var params = {
Source: "abc@gmail.com",
Template: "deviceUsageStatisticsEmailTemplate",
Destination: {
ToAddresses: ["xyz@gmail.com"]
},
TemplateData: message,
}
try {
let res = await ses.sendTemplatedEmail(params).promise()
console.log(res)
}
catch (err) {
console.log(err)
}
到目前为止我在测试中尝试过的内容:
function.test.js
test('should send templated email success', async () => {
jest.spyOn(console, 'log');
const mData = {};
ses.sendTemplatedEmail.mockImplementationOnce(async (params,callback) => {
callback(null,mData)
});
const message = 'mock message';
await index.sesSendEmail(message);
expect(aws.SES).toBeCalledWith({ apiVersion: '2020-12-01' });
expect(ses.sendTemplatedEmail).toBeCalledWith(
{
Source: 'abc@gmail.com',
Template: 'deviceUsageStatisticsEmailTemplate',
Destination: {
ToAddresses: ['xyz@gmail.com'],
},
TemplateData: message,
},
);
await expect(console.log).toBeCalledWith(mData);
});
test('should handle error', () => {
const arb = "network error"
ses.sendTemplatedEmail = jest.fn().mockImplementation(() => {
throw new Error(arb);
})
const message = 'mock message'
expect(() => { index.sesSendEmail(message) }).toThrow(arb);
});
});
问题:
报错
expect(jest.fn()).toBeCalledWith(...expected)
- Expected
+ Received
- Object {}
+ [TypeError: ses.sendTemplatedEmail(...).promise is not a function],
我尝试了模拟实现的变体,但无济于事。非常感谢 help/suggestion:)
更新
尝试要求 aws-sdk-mock
aws.mock('ses','sendTemplatedEmail',function(callback){callback(null,mData)})
但仍然出现错误
TypeError: Cannot stub non-existent own property ses
我会说模拟 aws sdk 本身并按照您通常的方式测试您的方法。一旦这样的库是 aws-sdk-mock
(https://www.npmjs.com/package/aws-sdk-mock)
像这样
const sinon = require("sinon");
const AWS = require("aws-sdk-mock");
test("should send templated email success", async () => {
const sendEmailStub = sinon.stub().resolves("resolved");
AWS.mock("SES", "sendTemplatedEmail", sendEmailStub);
const response = await sesSendEmail("{\"hi\": \"bye\"}");
expect(sendEmailStub.calledOnce).toEqual(true);
expect(sendEmailStub.calledWith(
{
"Source": "abc@gmail.com",
"Template": "deviceUsageStatisticsEmailTemplate",
"Destination": {
"ToAddresses": ["xyz@gmail.com"]
},
"TemplateData": "{\"hi\": \"bye\"}"
})).toEqual(true);
expect(response).toEqual("resolved");
AWS.restore();
});
test("should send templated email failure", async () => {
const sendEmailStubError = sinon.stub().rejects("rejected");
AWS.mock("SES", "sendTemplatedEmail", sendEmailStubError);
const response = await sesSendEmail("{\"hi\": \"bye\"}");
expect(sendEmailStubError.calledOnce).toEqual(true);
expect(sendEmailStubError.calledWith(
{
"Source": "abc@gmail.com",
"Template": "deviceUsageStatisticsEmailTemplate",
"Destination": {
"ToAddresses": ["xyz@gmail.com"]
},
"TemplateData": "{\"hi\": \"bye\"}"
})).toEqual(true);
expect(response.name).toEqual("rejected");
AWS.restore();
});
确保从您的原始方法返回响应和错误。
TypeError: ses.sendTemplatedEmail(...).promise is not a function
表示它期望调用 ses.sendTemplatedEmail()
的结果是一个对象,该对象具有名为 promise
.
要解决此问题,您将需要 return 模拟实现中的对象具有预期的 promise
属性。您还需要从模拟实现中删除 async
关键字,因为那样会 return 一个 Promise 对象,而不是具有 promise
属性.
这里是一个示例,它也 returns 来自 .promise()
的 Promise 对象,正如 sendTemplatedEmail.promise()
的生产实施所期望的那样:
ses.sendTemplatedEmail.mockImplementationOnce((params,callback) => ({
promise: () => Promise.resolve(callback(null,mData)),
}));