javascript – 如何使用jest在同一模块中模拟函数
作者:互联网
正确模拟以下示例的最佳方法是什么?
问题是在导入时间之后,foo会保留对原始未模拟条形的引用.
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()}`;
}
但这是p.在我看来,到处都是丑陋的:/
解决方法:
问题似乎与您期望如何解决bar的范围有关.
一方面,在module.js中导出两个函数(而不是一个包含这两个函数的对象).由于模块的导出方式,对导出的东西的容器的引用就像你提到的那样是导出.
另一方面,您处理导出(您使用别名模块)就像一个持有这些函数的对象并尝试替换其中一个函数(函数栏).
如果仔细观察你的foo实现,你实际上是对bar函数有一个固定的引用.
当您认为用新的替换了bar函数时,您实际上已经替换了module.test.js范围内的参考副本
为了让foo实际使用另一个版本的bar,你有两种可能:
>在module.js中导出一个类或一个实例,同时保存foo和bar方法:
Module.js:
export class MyModule {
function bar () {
return 'bar';
}
function foo () {
return `I am foo. bar is ${this.bar()}`;
}
}
请注意在foo方法中使用此关键字.
Module.test.js:
import { MyModule } from '../src/module'
describe('MyModule', () => {
//System under test :
const sut:MyModule = new MyModule();
let barSpy;
beforeEach(() => {
barSpy = jest.spyOn(
sut,
'bar'
).mockImplementation(jest.fn());
});
afterEach(() => {
barSpy.mockRestore();
});
it('foo', () => {
sut.bar.mockReturnValue('fake bar');
expect(sut.foo()).toEqual('I am foo. bar is fake bar');
});
});
>就像你说的那样,重写全局出口容器中的全局引用.这不是推荐的方法,因为如果没有正确地将导出重置为其初始状态,您可能会在其他测试中引入奇怪的行为.
标签:javascript,mocking,testing,jestjs 来源: https://codeday.me/bug/20190930/1834743.html