我有一个名为 helper.js 的文件,它包含两个函数
export const funcA = (key) => {
return funcB(key)
};
export const funcB = (key,prop) => {
return someObj;
};
我有我的 helper.spec.js 来测试 helper.js 文件的功能。
import {funcA,funcB} from 'helper';
describe('helper', () => {
test('testFuncB', () => {
}
test('testFuncA', () => {
}
}
funcB 的测试非常简单,我只是调用它并期待 someObj
问题是测试 funcA,为了测试它我想模拟 funcB 的响应。
我希望 testFuncB 调用实际的 funcB 和 testFuncA 调用模拟的 funcB
如何在我的两个测试中实现 funcB 的模拟和原始?
这不是重复的。这是一种不同的情况:它们仅模拟内部调用的函数,如果我删除 testFuncB,那么它将是相同的,但我也必须对 testFuncB 执行测试。
最佳答案
如果一个 ES6 模块直接导出两个函数(不在类、对象等中,只是像问题中那样直接导出函数)并且一个直接调用另一个,那么那个调用不能被模拟强>.
在这种情况下,funcB
不能在funcA
内被模拟当前编写代码的方式。
模拟替换了 funcB
的模块导出 ,但是funcA
不为 funcB
调用模块导出 , 它只是调用 funcB
直接。
模拟 funcB
在 funcA
内要求 funcA
为 funcB
调用模块导出 .
这可以通过以下两种方式之一完成:
移动funcB
到自己的模块
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();
});
});
将模块导入自身
"ES6 modules support cyclic dependencies automatically"所以它对 import
完全有效一个模块自身,以便模块内的函数可以为模块中的其他函数调用模块导出:
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();
});
});
关于javascript - Jest 模拟内部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56209707/