如果一个 ES6 module直接导出两个函数(不在类、对象等内,只是直接导出问题中的函数)并且一个直接调用另一个,那么该调用不能被模拟。
在这种情况下,funcB
不能嘲笑内funcA
代码当前编写方式。
有模拟替换module出口的funcB
,但funcA
不调用module输出的funcB
,它只是调用funcB
直接。
惩戒funcB
内funcA
需要funcA
调用module出口的funcB
。
这可以通过以下两种方式之一完成:
移动funcB
到它自己的module
funcB.js
export const funcB = () => {
return 'original';
};
helper.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();
});
});
将module导入自身
“ES6 module自动支持循环依赖”,因此它对import
module本身完全有效,以便module内的函数可以调用module中其他函数的module导出:
helper.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();
});
});