【问题标题】:How do I mock express.Application with Jest?如何用 Jest 模拟 express.Application?
【发布时间】:2019-01-30 22:01:27
【问题描述】:

一些将 express 作为参数的类(基本 DI):

class App {
  constructor(express: express.Application) { /* ... */ }
}

我的测试:

// this doesn't work ("argument not assignable"):
//const expressMock = jest.mock("express");
//let app = new App(expressMock);

// so how do I mock it?
const expressMock = ???
let app = new App(expressMock);

如何用 Jest 模拟 express.Application?整个事情,不仅仅是一个请求,或路由等。

【问题讨论】:

    标签: node.js typescript express mocking jestjs


    【解决方案1】:

    从技术上讲,express.Application 不能被模拟,它是一个接口。它是一个它所代表的对象,应该被模拟。

    正如jest.mock documentation 所说,它

    返回用于链接的笑话对象。

    所以这不是检索模拟对象的正确方法:

    const expressMock = jest.mock("express");
    

    一个正确的应该是

    jest.mock("express");
    ...
    const expressMock = require("express");
    

    此外,App 接受的不是express 工厂函数而是应用程序对象,这是express() 调用的结果。

    jest.mock 没有工厂函数会导致自动模拟 express 工厂,它不会生成正确的应用程序对象。

    由于expressMock 在测试中直接传递给App,因此没有必要模拟 Express 模块。可以改为传递包含最少实现的模拟:

    const expressMock = {
      use: jest.fn(),
      ...
    } as any as express.Application;
    
    let app = new App(expressMock);
    

    【讨论】:

    • 谢谢,这很有帮助。您说的是“自动模拟的快递工厂,它不会产生正确的应用程序对象”。 - 如何生成模拟的应用程序对象?
    • const expressMock = { use: jest.fn(), ... }。如果你需要模拟一个模块,那就是jest.mock("express", () => () => expressMock)
    • express.application 包含应用实例包含的所有方法。您可以遍历 original express.application 键并使用这些存根方法创建一个模拟对象,它们还需要返回 obj,因为 Express 使用链接。但问题是不是每个方法都链接。例如。 app.get('value') 是配置 getter 并返回一个值,而 app.get('path', ...) 是路由器并返回 app。模拟不可避免地会变得杂乱无章,并且可能存在错误。
    • JS 中有自动模拟库,但它们可能不适用于 Express,因为它是老式的并且不使用 ES6 类。他们也不会用链接来覆盖这个东西。我通常建议不要使用自动模拟,尤其是使用 Express。它导致更松散的测试,当它们失败时更难调试。至少在 JS 中测试你的单元到底做了什么是一个很好的做法。如果您使用来自 app 的 5 种方法,请仅模拟它们。如果您更改应用程序以使测试无效(例如使用第 6 种方法),则测试将失败。这比在应该失败时不会失败的测试要好得多。
    • 很高兴它有帮助。我认为不同之处在于,由于 JS 的动态特性,开发人员可以自己维护测试中的类型安全并使模拟符合预期的接口。在这种情况下,来自 TS 的帮助非常有限。
    猜你喜欢
    • 2018-12-25
    • 2021-02-15
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    相关资源
    最近更新 更多