使用 Jest 创建的部分模块模拟函数不被被测函数调用 [英] Partial module mock function created using Jest is not called by function under test

查看:16
本文介绍了使用 Jest 创建的部分模块模拟函数不被被测函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(基于已经此处.)对于下面的模块,

(Based on the examples kindly provided already here.) For the module below,

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

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

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

我想编写一个测试来验证默认导出的函数是否正确调用了草莓函数>.为了实现这一点,我尝试了以下测试,

I would like to write a test that will verify that the default exported function correctly invokes the function strawberry. To achieve this I attempted the following test,

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

然而,没有调用模拟函数,而是调用了实际函数.

However the mocked function is not called, instead, the actual function gets called.

 × 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 "

这是预期的吗?

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

Is my test valid? Have I missed anything in my test?

推荐答案

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

What's happening is that by the time Jest imports fruit.js to generate a mock from it, the anonymous function in your default export has already grabbed a reference to the actual strawberry in its closure.

所以 Jest 所做的就是为以后导入它的任何其他模块模拟 strawberry,例如您的测试套件.

So all Jest is doing is mocking strawberry for any other modules that import it later on, e.g. your test suite.

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

This article explains some ways to work around this: https://medium.com/@qjli/how-to-mock-specific-module-function-in-jest-715e39a391f4

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

My suggestion is to consider refactoring your logic before employing any workarounds:

  • fruit.js 中的某些函数是否用作实现细节或用于分解逻辑?也许您可以将它们视为私有类方法,并通过 defaultExport 本身来测试它们.

  • Do some functions in fruit.js serve as implementation detail or used to factor out logic? Maybe you can treat them like private class methods and test them through defaultExport itself.

如果它们的逻辑如此独立以至于需要在测试之间进行模拟,那么这些函数是否应该驻留在单独的模块中?

If their logic is so independent that it needs to be mocked out between tests, maybe the functions should reside in separate modules?

这篇关于使用 Jest 创建的部分模块模拟函数不被被测函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆