node.js - 用玩笑模拟 nodemailer.createTransport.sendMail
问题描述
我有一些使用nodemailer模块的代码。
在路由器(router.js)中,我有
const transporter = nodeMailer.createTransport(emailArgs);
然后在路线(/login
)内我有:
...
return transporter.sendMail(mailOptions);
我正在尝试使用jest
测试框架测试这条路线。我在模拟对 的调用时遇到了一些麻烦sendMail
。我读了这篇关于如何使用 jest mocking 的不错的博文,但我收到了这个错误:
TypeError:无法读取未定义的属性“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
});
});
所以我的问题是如何模拟模块返回的类实例的方法?
解决方案
我遇到了同样的问题并找到了解决方案。这是我发现的:
jest.mock("nodemailer");
你告诉 jest用nodemailer
自动模拟替换。这意味着 的每个属性nodemailer
都被一个空的模拟函数替换(类似于jest.fn()
)。
这就是您收到错误的原因TypeError: Cannot read property 'sendMail' of undefined
。为了有一些有用的东西,你必须定义nodemailer.createTransport
.
在我们的例子中,我们不希望有一个带有 property 的对象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();
});
});
推荐阅读
- java - cvc-complex-type.2.4.c:匹配通配符是严格的,但找不到元素“jaxrs:server”的声明
- javascript - 打鼹鼠游戏麻烦
- php - Laravel 如何在分类帖子上添加 orderBy
- scala - Gatling.bat 命令行选项,它们是如何工作的?
- sql-server - 如何使用经典 ASP 更新 SQL 中的多条记录
- oracle - pl sql插入到过程和动态变量中
- python - 如何仅提取每个 tr 中的第一个 td[0]
- python - 目标检测模型的性能上下跳跃
- typescript - “此类型上不应存在成员”的 TypeScript 类型声明?
- ruby - Ruby四位数字,如何检查它们是否是两个相同的数字