简体   繁体   English

jest.spyOn 相当于 jest.mock

[英]jest.spyOn equivalent for jest.mock

Mock a whole module but retain original module logic.模拟整个模块但保留原始模块逻辑。 Similar to jest.spyOn default behaviour, where the original method is called.类似于jest.spyOn默认行为,其中调用原始方法。

Using jest.mock allows performing the assertions needed, but doesn't execute the original logic and sometimes I want that logic to be executed.使用jest.mock允许执行所需的断言,但不执行原始逻辑,有时我希望执行该逻辑。 Using jest.spyOn allows assertion and can execute original logic, but only on named exports of the module, which is generally useful but not when the method is exported as default or like in the sample code below.使用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(...)
})

Maybe I missed something simple, but so far docs or google fu hasn't yielded any results.也许我错过了一些简单的东西,但到目前为止 docs 或 google fu 还没有产生任何结果。

There is no way to mock a module and spy on its methods.没有办法模拟一个模块并监视它的方法。 The reason is that jest really replace the module with the mock.原因是 jest 真的用模拟替换了模块。

I'm currently doing it like this我目前正在这样做

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

this makes the module retain the original implementation but since all the exports are wrapped in jest.fn they can now be mocked with a different implementation in each particular test这使模块保留原始实现,但由于所有导出都包含在jest.fn ,因此现在可以在每个特定测试中使用不同的实现来jest.fn它们

This came up often enough that I just decided to write my own library for generating auto mocks of modules that keep the original implementation but can be overridden just like jest.spyOn .这经常出现,以至于我决定编写自己的库来生成模块的自动模拟,这些模块保留原始实现但可以像jest.spyOn一样被覆盖。

Jest Mock Module Jest 模拟模块

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);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM