我有一个名为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",因此将一个模块抄入其自身是完全有效的,以便该模块中的功能可以为模块中的其他功能调用模块导出:
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 - 开玩笑的模拟内部功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56209707/