在ExpresS API中,我使用邮戳库发送电子邮件,发送方式如下:
var postmark = require("postmark");
var client = new postmark.Client("aaaa-bbbbb-cccc");
然后用于发送密码重置邮件:
client.sendEmailWithTemplate(
// Options here
);
现在,我想测试这个函数已被调用,但我很难找到如何模拟/监视这个。
我尝试过以下(简化):
const request = require("supertest");
const app = require("../server/app");
const postmark = require("postmark");
jest.mock("postmark");
describe("API Tests", () => {
test("it should give a reset link when requesting with existing e-mail address", () => {
return request(app)
.post("/api/auth/passwordreset")
.send({
email: "user1@test.test"
})
.then(response => {
expect(postmark.Client).toHaveBeenCalled();
});
});
});
这样做有效,但它只测试是否使用了邮戳,因为我无法弄清楚如何实际测试client.sendEmailWithTemplate
方法
有关如何完成此任务的任何建议?
编辑:跟进@samanime回答我创建了一个回购来说明挑战'
答案 0 :(得分:1)
您可以专门模拟被模拟的Client
返回的postmark
函数,以返回具有模拟函数的对象。
在Jest中,您可以通过创建与node_modules
相同级别的__mocks__
文件夹,为node_modules
提供特定的模拟代码,即
/project-root
/node_modules
/__mocks__
注意,这是两侧的两个下划线。
在那里,创建一个名为<package_name>.js
的函数(在您的情况下为postmark.js
)。然后,当您使用mock
时,它将加载由此导出的任何内容。
在该文件中,您可以根据需要进行模拟。这样的事可能会奏效:
// global jest
module.exports = {
Client: jest.fn(() => ({
sendEmailWithTemplate: jest.fn(() => {})
}))
};
它不必像这样紧凑,但基本上它使postmark
有一个名为Client
的函数,它返回一个具有一个名为sendEmailWithTemplate
的函数的对象,两者都是模拟/间谍。
然后你可以检查是否调用postmark.Client.sendEmailWithTemplate
。
一个问题是你需要确保在两次测试之间重置所有这些。您可以在beforeEach()
中手动执行此操作,但如果您要重复使用它,我想添加一个名为__reset()
的额外函数,它将重置代码并调用它:
// global jest
const mockedPostmark = {
Client: jest.fn(() => ({
sendEmailWithTemplate: jest.fn(() => {})
}))
};
mockedPostmark.__reset = () => {
mockedPostmark.Client.mockClear();
mockedPostmark.Client.sendEmailWithTemplate.mockClear();
};
module.exports = mockedPostmark;
您也可以根据需要添加其他功能。