jest.spyOn 相当于 jest.mock
jest.spyOn equivalent for jest.mock
模拟整个模块但保留原始模块逻辑。类似于 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(...)
})
也许我漏掉了一些简单的东西,但到目前为止文档或google fu 还没有产生任何结果。
无法模拟模块并监视其方法。原因是 jest 真的用 mock 替换了模块。
我目前是这样做的
jest.mock('./somepath', () => (
Object.fromEntries(
Object.entries(jest.requireActual('./somepath'))
.map(([key, value]) => [key, jest.fn(value)])
)
))
这使得模块保留原始实现,但由于所有导出都包含在 jest.fn
中,现在可以在每个特定测试中使用不同的实现来模拟它们
这经常出现,所以我决定编写自己的库来生成模块的自动模拟,这些模块保留原始实现但可以像 jest.spyOn
一样被覆盖。
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);
});
模拟整个模块但保留原始模块逻辑。类似于 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(...)
})
也许我漏掉了一些简单的东西,但到目前为止文档或google fu 还没有产生任何结果。
无法模拟模块并监视其方法。原因是 jest 真的用 mock 替换了模块。
我目前是这样做的
jest.mock('./somepath', () => (
Object.fromEntries(
Object.entries(jest.requireActual('./somepath'))
.map(([key, value]) => [key, jest.fn(value)])
)
))
这使得模块保留原始实现,但由于所有导出都包含在 jest.fn
中,现在可以在每个特定测试中使用不同的实现来模拟它们
这经常出现,所以我决定编写自己的库来生成模块的自动模拟,这些模块保留原始实现但可以像 jest.spyOn
一样被覆盖。
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);
});