javascript Jest 模拟内部函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/51269431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jest mock inner function
提问by Alexander Gorelik
I have one file called helper.jsthat consist of two functions
我有一个名为helper.js 的文件,它包含两个函数
export const funcA = (key) => {
return funcB(key)
};
export const funcB = (key,prop) => {
return someObj;
};
I have my helper.spec.jsto test the helper.js file functions.
我有我的helper.spec.js来测试 helper.js 文件功能。
import {funcA,funcB} from 'helper';
describe('helper', () => {
test('testFuncB', () => {
}
test('testFuncA', () => {
}
}
The test for funcB is pretty simple i just call it and expect someObj
The problem is to test funcA, in order to test it i want to mock the response of funcB.
funcB 的测试非常简单,我只是调用它并期望someObj
问题是测试 funcA,为了测试它我想模拟 funcB 的响应。
I want testFuncBcall the actual funcBand testFuncAcall mocked funcB
我想要testFuncB调用实际的funcB和testFuncA调用模拟的 funcB
How can i achieve funcB to be mocked and original in my two tests?
我怎样才能在我的两个测试中实现 funcB 被模拟和原创?
This is not a duplicate. It is a different case: they mock inner called functions only, if I remove the testFuncB then it will be the same but I must perform test on testFuncB too.
这不是重复的。这是一个不同的情况:他们只模拟内部调用的函数,如果我删除 testFuncB 那么它会是一样的,但我也必须对 testFuncB 执行测试。
回答by Brian Adams
If an ES6 module directly exports two functions (not within a class, object, etc., just directly exports the functions like in the question) and one directly calls the other, then that call cannot be mocked.
如果一个 ES6 模块直接导出两个函数(不在类、对象等内,只是直接导出问题中的函数)并且一个直接调用另一个,那么该调用不能被模拟。
In this case, funcBcannot be mockedwithin funcAthe way the code is currently written.
在这种情况下,funcB不能嘲笑内funcA代码当前编写方式。
A mock replaces the module exportfor funcB, but funcAdoesn't call the module exportfor funcB, it just calls funcBdirectly.
有模拟替换模块出口的funcB,但funcA不调用模块输出的funcB,它只是调用funcB直接。
Mocking funcBwithin funcArequires that funcAcall the module exportfor funcB.
惩戒funcB内funcA需要funcA调用模块出口的funcB。
That can be done in one of two ways:
这可以通过以下两种方式之一完成:
Move funcBto its own module
移动funcB到它自己的模块
funcB.js
funcB.js
export const funcB = () => {
return 'original';
};
helper.js
helper.js
import { funcB } from './funcB';
export const funcA = () => {
return funcB();
};
helper.spec.js
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();
});
});
Import the module into itself
将模块导入自身
"ES6 modules support cyclic dependencies automatically"so it is perfectly valid to importa module into itself so that functions within the module can call the module exportfor other functions in the module:
“ES6 模块自动支持循环依赖”,因此它对import模块本身完全有效,以便模块内的函数可以调用模块中其他函数的模块导出:
helper.js
helper.js
import * as helper from './helper';
export const funcA = () => {
return helper.funcB();
};
export const funcB = () => {
return 'original';
};
helper.spec.js
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();
});
});
回答by hannad rehman
import * as helper from 'helper';
describe('helper', () => {
it('should test testFuncA', () => {
const mockTestFuncB = jest.mock();
// spy on calls to testFuncB and respond with a mock function
mockTestFuncB.spyOn(helper, 'testFuncB').mockReturnValue(/*your expected return value*/);
// test logic
// Restore helper.testFuncB to it's original function
helper.testFuncB.mockRestore();
}
}
回答by Red Mercury
I think this might work
我认为这可能有效
import * as helper from 'helper';
describe('helper', () => {
test('testFuncB', () => {
}
test('testFuncA', () => {
const mockTestFuncB = jest.mock();
// spy on calls to testFuncB and respond with a mock function
jest.spyOn(helper, 'testFuncB').mockImplementationOnce(mockTestFuncB);
// Do the testing ...
// Restore helper.testFuncB to it's original function
helper.testFuncB.mockRestore();
}
}

