正确模拟以下示例的最佳方法是什么?
问题是在导入时间之后,foo
保留对原始未模拟的 bar
的引用。
module.js
:
export function bar () {
return 'bar';
}
export function foo () {
return `I am foo. bar is ${bar()}`;
}
module.test.js
:
import * as module from '../src/module';
describe('module', () => {
let barSpy;
beforeEach(() => {
barSpy = jest.spyOn(
module,
'bar'
).mockImplementation(jest.fn());
});
afterEach(() => {
barSpy.mockRestore();
});
it('foo', () => {
console.log(jest.isMockFunction(module.bar)); // outputs true
module.bar.mockReturnValue('fake bar');
console.log(module.bar()); // outputs 'fake bar';
expect(module.foo()).toEqual('I am foo. bar is fake bar');
/**
* does not work! we get the following:
*
* Expected value to equal:
* "I am foo. bar is fake bar"
* Received:
* "I am foo. bar is bar"
*/
});
});
我可以改变:
export function foo () {
return `I am foo. bar is ${bar()}`;
}
到:
export function foo () {
return `I am foo. bar is ${exports.bar()}`;
}
但我认为在任何地方都这样做是非常丑陋的。
最佳答案
另一种解决方案是将模块导入到它自己的代码文件中,并使用所有导出实体的导入实例。像这样:
import * as thisModule from './module';
export function bar () {
return 'bar';
}
export function foo () {
return `I am foo. bar is ${thisModule.bar()}`;
}
现在模拟 bar
真的很容易,因为 foo
也使用了 bar
的导出实例:
import * as module from '../src/module';
describe('module', () => {
it('foo', () => {
spyOn(module, 'bar').and.returnValue('fake bar');
expect(module.foo()).toEqual('I am foo. bar is fake bar');
});
});
将模块导入自己的代码看起来很奇怪,但由于 ES6 对循环导入的支持,它工作起来非常顺利。
关于javascript - 如何使用 Jest 模拟同一模块中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45111198/