如果一个 ES6 模块直接导出两个函数(不在类、对象等内,只是直接导出问题中的函数)并且一个直接调用另一个,那么该调用不能被模拟。
在这种情况下,funcB 不能以funcA当前编写代码的方式进行模拟。
mock 替换了模块 export for funcB,但funcA不调用模块 export for funcB,它只是funcB直接调用。
内部funcB模拟funcA需要funcA调用模块导出。funcB
这可以通过以下两种方式之一完成:
移动funcB到自己的模块
funcB.js
export const funcB = () => {
return 'original';
};
助手.js
import { funcB } from './funcB';
export const funcA = () => {
return funcB();
};
helper.spec.js
import * as funcBModule from './funcB';
import { funcA } from './helper';
describe('helper', () => {
test('test funcB', () => {
expect(funcBModule.funcB()).toBe('original'); // Success!
});
test('test funcA', () => {
const spy = jest.spyOn(funcBModule, 'funcB');
spy.mockReturnValue('mocked');
expect(funcA()).toBe('mocked'); // Success!
spy.mockRestore();
});
});
将模块导入自身
“ES6 模块自动支持循环依赖”import ,因此它对模块自身完全有效,因此模块内的函数可以为模块中的其他函数调用模块导出:
助手.js
import * as helper from './helper';
export const funcA = () => {
return helper.funcB();
};
export const funcB = () => {
return 'original';
};
helper.spec.js
import * as helper from './helper';
describe('helper', () => {
test('test funcB', () => {
expect(helper.funcB()).toBe('original'); // Success!
});
test('test funcA', () => {
const spy = jest.spyOn(helper, 'funcB');
spy.mockReturnValue('mocked');
expect(helper.funcA()).toBe('mocked'); // Success!
spy.mockRestore();
});
});