【问题标题】:jest.spyOn equivalent for jest.mockjest.spyOn 等效于 jest.mock
【发布时间】:2019-06-16 13:46:17
【问题描述】:

模拟整个模块,但保留原始模块逻辑。类似于jest.spyOn 默认行为,调用原始方法。

使用jest.mock 允许执行所需的断言,但不执行原始逻辑,有时我希望执行该逻辑。 使用jest.spyOn 允许断言并且可以执行原始逻辑,但仅限于模块的命名导出,这通常很有用,但当方法导出为默认值或类似下面的示例代码时,它就没有用了。

// moduleToMock.js
function doSomething(..args) {...}

doSomething.myWay = function myWay(...args) {...}

module.exports = doSomething

// moduleUsingModuleToMock.js
const doSomething = require('moduleToMock')

function doManyThings() {
    doSomething(...)
    doSomething.myWay(...)
}

module.exports = {
    doManyThings,
}

// moduleUsingModuleToMock.test.js
// --
// some way to mock `moduleToMock` that still executes original logic
// --
const doSomething = require('moduleUsingModuleToMock')
it('correctly does many things', () => {
    doManyThings()
    expect(doSomething).toBeCalledWith(...)
    expect(doSomething.myWay).toBeCalledWith(...)
})

也许我错过了一些简单的事情,但到目前为止 docs 或 google fu 还没有产生任何结果。

【问题讨论】:

    标签: javascript mocking jestjs spy


    【解决方案1】:

    没有办法模拟一个模块并监视它的方法。原因是 jest 真的用 mock 替换了模块。

    【讨论】:

    • 我不认为这会执行原始模块中的逻辑,它只是提供了一个模拟接口。 jest.spyOn(module, 'methodName') 仍然执行方法的原始逻辑以及提供模拟接口,我正在寻找模块级别的等效项。
    • 抱歉错过了执行原始逻辑的部分
    【解决方案2】:

    我现在是这样的

    jest.mock('./somepath', () => (
      Object.fromEntries(
        Object.entries(jest.requireActual('./somepath'))
          .map(([key, value]) => [key, jest.fn(value)])
      )
    ))
    

    这使得模块保留了原始实现,但由于所有导出都包含在 jest.fn 中,现在可以在每个特定测试中使用不同的实现来模拟它们

    【讨论】:

      【解决方案3】:

      这种情况经常出现,以至于我决定编写自己的库来生成模块的自动模拟,这些模块保留原始实现但可以像 jest.spyOn 一样被覆盖。

      Jest Mock Module

      import * as mock from "jest-mock-module";
      mock.extend(jest); // optionally extend jest to use the "jest.spy" syntax
      jest.spy("src/moduleToMock"); // Placed before other imports like "jest.mock".
      
      import moduleToMock from "src/moduleToMock";
      import moduleToTest from "src/moduleToTest";
      
      it("does a thing", () => {
        moduleToTest.callFunctionThatUsesModuleToMock();
        expect(moduleToMock.usedFunction).toHaveBeenCalledTimes(1);
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-01
        • 1970-01-01
        • 2019-06-29
        • 2021-09-22
        • 1970-01-01
        • 1970-01-01
        • 2012-10-21
        • 2018-10-05
        相关资源
        最近更新 更多