手动模拟不适用于 Jest

Posted

技术标签:

【中文标题】手动模拟不适用于 Jest【英文标题】:Manual mock not working in with Jest 【发布时间】:2018-09-16 13:47:54 【问题描述】:

有人可以帮我在 Jest 中手动模拟吗? :) 我尝试让 Jest 使用模拟而不是实际模块。

我的测试:

// __tests__/mockTest.js

import ModuleA from "../src/ModuleA"

describe("ModuleA", () => 
    beforeEach(() => 
        jest.mock("../src/ModuleA")
    )

    it("should return the mock name", () => 
        const name = ModuleA.getModuleName()
        expect(name).toBe("mockModuleA")
    )
)

我的代码:

// src/ModuleA.js
export default 
    getModuleName: () => "moduleA"


// src/__mocks__/ModuleA.js
export default 
    getModuleName: () => "mockModuleA"

我想我遵循了documentation 所说的关于手动模拟的所有内容,但也许我在这里忽略了一些东西? 这是我的结果:

Expected value to be:
      "mockModuleA"
Received:
      "moduleA"

【问题讨论】:

【参考方案1】:

尽可能使用babel-jest 转换提升模块模拟,因此这将导致模拟模块:

import ModuleA from "../src/ModuleA"
jest.mock("../src/ModuleA") // hoisted to be evaluated prior to import

如果一个模块应该在每个测试基础上进行模拟,这将不起作用,因为jest.mock 驻留在beforeEach 函数中。

在这种情况下应该使用require

describe("ModuleA", () => 
    beforeEach(() => 
        jest.mock("../src/ModuleA")
    )

    it("should return the mock name", () => 
        const ModuleA = require("../src/ModuleA").default;
        const name = ModuleA.getModuleName()
        expect(name).toBe("mockModuleA")
    )
)

由于它不是导出,而是默认导出中的一个方法应该被模拟,这也可以通过模拟 ModuleA.getModuleName 而不是整个模块来实现。

【讨论】:

好吧,我明白了。我也在尝试使用require,但不知道.default。解决方案奏效了,tnx :) 我也在beforeEach 之外尝试过,正如您在第一部分中解释的那样,这似乎也奏效了。非常感谢:) 感谢您开玩笑地解释吊装的工作原理 不错的答案。但我仍然不太明白为什么require.default 有效,但import 无效。我想我没看懂这句话Since it's not an export but a method in default export that should be mocked @drlingyi 用import 模拟不起作用,因为jest.mockimport 之后评估并且不能影响它,jest.mock 用于嵌套范围会阻止它被提升。这意味着它可能是jest.spyOn(ModuleA, 'getModuleName').mock... 而不是 jest.mock。 ES 模块 * export 是只读的,不应直接修改为 mock 或 spy 命名的导出,但此限制不适用于 default 对象。

以上是关于手动模拟不适用于 Jest的主要内容,如果未能解决你的问题,请参考以下文章

使用 Typescript 从 Jest 手动模拟中导入函数

使用 Jest 手动模拟 React-Intl 进行快照测试

笑话模拟工厂不适用于模拟类

Express JS 代码不适用于 pm2,但手动启动时(“node .”/“node index.js”)

babel-plugin-module-resolver 不适用于 jest

Espresso 不适用于 NineOldAndroids 动画?