(基于here已经提供的示例。) 对于下面的模块,
// fruit.js
export const apple = 'apple';
export const strawberry = () => 'strawberry';
export default () => `banana and ${strawberry()} `;
我想编写一个测试来验证 默认 导出的函数是否正确调用了函数 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 "
这是预期的吗?
我的考试有效吗?我考试中错过了什么吗?
答案 0 :(得分:1)
正在发生的事情是,当Jest导入fruit.js
来从中生成模拟时,默认导出中的匿名函数已经在其关闭时获取了对实际strawberry
的引用。
因此,Jest所做的全部工作就是为以后导入其的任何其他模块模拟strawberry
。您的测试套件。
本文介绍了解决此问题的一些方法:https://medium.com/@qjli/how-to-mock-specific-module-function-in-jest-715e39a391f4
我的建议是在采用任何变通办法之前考虑重构您的逻辑:
fruit.js
中的某些功能是否充当实现细节或用于分解逻辑?也许您可以像对待私有类方法一样对待它们,并通过defaultExport
本身对其进行测试。
如果它们的逻辑是如此独立,以至于需要在测试之间进行模拟,那么这些功能应该驻留在单独的模块中吗?