我有一些使用 nodemailer 的代码模块。
在路由器(router.js)中,我有
const transporter = nodeMailer.createTransport(emailArgs);
然后在路线(/login
)内我有:
...
return transporter.sendMail(mailOptions);
我正在尝试使用 jest
测试框架来测试此路线。我在模拟对 sendMail
的调用时遇到了一些问题。我读过this nice blogpost关于如何使用 Jest 模拟,但我收到此错误:
TypeError: Cannot read property 'sendMail' of undefined
事实上,当我检查 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
});
});
所以我的问题是如何模拟模块返回的类实例的方法?
最佳答案
我遇到了同样的问题并找到了解决方案。这是我的发现:
与 jest.mock("nodemailer");
你告诉 jest 替换 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();
});
});
关于node.js - 用 Jest 模拟 nodemailer.createTransport.sendMail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53420562/