【问题标题】:Partial module mock function created using Jest is not called by function under test使用 Jest 创建的部分模块模拟函数未被被测函数调用
【发布时间】:2019-01-30 04:42:21
【问题描述】:

(基于已经here提供的示例。) 对于下面的模块,

// fruit.js
export const apple = 'apple';

export const strawberry = () => 'strawberry';

export default () => `banana and ${strawberry()} `;

我想编写一个测试来验证 default 导出的函数是否正确调用函数 strawberry。 为此,我尝试了以下测试,

// partial_mock.js
import defaultExport, { strawberry } from '../fruit';

jest.mock('../fruit', () => {
  const originalModule = require.requireActual('../fruit');
  const mockedModule = jest.genMockFromModule('../fruit');

  // Mock the exported 'strawberry' function.
  return Object.assign({}, mockedModule, originalModule, {
    strawberry: jest.fn(() => 'mocked strawberry'),
  });
});

it('does a partial mock', () => {
  expect(strawberry()).toBe('mocked strawberry');

  const defaultExportResult = defaultExport();
  expect(defaultExportResult).toBe('banana and mocked strawberry');
});

然而,模拟函数没有被调用,而是实际的函数被调用。

 × does a partial mock (21ms)

  ● does a partial mock

    expect(received).toBe(expected) // Object.is equality

    Expected: "banana and mocked strawberry"
    Received: "banana and strawberry "

这是预期的吗?

我的测试有效吗?我在测试中遗漏了什么吗?

【问题讨论】:

    标签: jestjs


    【解决方案1】:

    发生的情况是,当 Jest 导入 fruit.js 以从中生成模拟时,默认导出中的匿名函数已经在其闭包中获取了对实际 strawberry 的引用。

    因此,Jest 所做的只是模拟 strawberry 用于稍后导入它的任何其他模块,例如你的测试套件。

    本文介绍了一些解决此问题的方法:https://medium.com/@qjli/how-to-mock-specific-module-function-in-jest-715e39a391f4

    我的建议是在采用任何变通方法之前考虑重构您的逻辑:

    • fruit.js 中的某些函数是用作实现细节还是用于分解逻辑?或许你可以把它们当成私有类方法,通过defaultExport本身来测试。

    • 如果他们的逻辑是如此独立以至于需要在测试之间模拟出来,也许这些函数应该驻留在单独的模块中?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-03
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 2019-03-28
      • 2020-06-14
      • 2021-03-26
      • 2018-10-01
      相关资源
      最近更新 更多