Dan*_*ats 8 unit-testing mocking node.js nodemailer jestjs
我有一些使用nodemailer模块的代码。
在路由器(router.js)中,我有
const transporter = nodeMailer.createTransport(emailArgs);
Run Code Online (Sandbox Code Playgroud)
然后在路线(/login)内我有:
...
return transporter.sendMail(mailOptions);
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用jest测试框架测试这条路线。我在模拟对sendMail. 我读了这篇关于如何使用 jest mocking 的好博文,但我收到了这个错误:
类型错误:无法读取未定义的属性“sendMail”
事实上,当我检查transporter它的值是未定义的。
这是我的测试代码(不起作用):
import request from "supertest";
import router from "./router";
jest.mock("nodemailer");
describe("", () => {
...
test("", async () => {
// 1 - 200 status code; 2 - check email was sent
expect.assertions(2);
const response = await request(router)
.post("/login")
// global variable
.send({ "email": email })
.set("Accept", "application/json")
.expect("Content-Type", /json/);
// should complete successfully
expect(response.status).toBe(200);
// TODO not sure how to express the expect statement here
});
});
Run Code Online (Sandbox Code Playgroud)
所以我的问题是如何模拟模块返回的类实例的方法?
小智 10
为了模拟 nodemailer 模块,我这样做
jest.mock('nodemailer', () => ({
createTransport: jest.fn().mockReturnValue({
sendMail: jest.fn().mockReturnValue((mailoptions, callback) => {})
})
}));
Run Code Online (Sandbox Code Playgroud)
奇迹般有效
如果需要评估.toBeCalledWith()等,您还可以定义一个模拟函数:
const sendMailMock = jest.fn()
jest.mock('nodemailer', () => ({
createTransport: jest.fn().mockImplementation(() => ({
sendMail: sendMailMock,
})),
}))
Run Code Online (Sandbox Code Playgroud)
我遇到了同样的问题并找到了解决方案。这是我发现的:
和 jest.mock("nodemailer");你告诉笑话来代替nodemailer与自动模拟。这意味着 的每个属性nodemailer都替换为一个空的模拟函数(类似于jest.fn())。
这就是你得到错误的原因 TypeError: Cannot read property 'sendMail' of undefined。为了有一些有用的东西,你必须定义nodemailer.createTransport.
在我们的例子中,我们不想拥有一个带有属性的对象 sendMail。我们可以用nodemailer.createTransport.mockReturnValue({"sendMail": jest.fn()});. 由于您可能想要测试是否sendMail被调用,因此最好事先创建该模拟函数。
这是您的测试代码的完整示例:
import request from "supertest";
import router from "./router";
const sendMailMock = jest.fn(); // this will return undefined if .sendMail() is called
// In order to return a specific value you can use this instead
// const sendMailMock = jest.fn().mockReturnValue(/* Whatever you would expect as return value */);
jest.mock("nodemailer");
const nodemailer = require("nodemailer"); //doesn't work with import. idk why
nodemailer.createTransport.mockReturnValue({"sendMail": sendMailMock});
beforeEach( () => {
sendMailMock.mockClear();
nodemailer.createTransport.mockClear();
});
describe("", () => {
...
test("", async () => {
// 1 - 200 status code; 2 - check email was sent
expect.assertions(2);
const response = await request(router)
.post("/login")
// global variable
.send({ "email": email })
.set("Accept", "application/json")
.expect("Content-Type", /json/);
// should complete successfully
expect(response.status).toBe(200);
// TODO not sure how to express the expect statement here
expect(sendMailMock).toHaveBeenCalled();
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4806 次 |
| 最近记录: |