javascript - 使用 Jest 监视启动的模块

标签 javascript node.js unit-testing jestjs

在 ExpressS API 中,我使用 Postmark 库发送电子邮件,其启动方式如下:

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 的回答,我创建了一个存储库来说明“挑战”

https://github.com/Hyra/jest_test_example

最佳答案

您可以专门模拟 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 的函数,两者都是模拟/ spy 。

然后你可以检查是否 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;

您还可以根据需要添加其他功能。

关于javascript - 使用 Jest 监视启动的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49681047/

相关文章:

javascript - jQuery 调整大小功能出现问题

javascript - 我应该如何使用图像来触发 Javascript?

node.js - 在nodejs/expressjs中使用RedisStore

javascript - 需要子进程为空

unit-testing - 如何在JIRA中记录和运行测试用例?

javascript - 强制粘贴事件以 base64 编码图像

javascript - 使用 javascript 使用模数将工作日的选择减去 8 天或更多天时出现问题

json - 使用 Express.js 动态更改 JSON 间距

Java:如何对使用 REST 服务的抽象类进行单元测试

java - 快速将assertXY语句从JUnit4迁移到Junit5?