如何使用模拟来计算通过call
或apply
进行的函数调用
// mylib.js
module.exports = {
requestInfo: function(model, id) {
return `The information for ${model} with ID ${id} is foobar`;
},
execute: function(name) {
return this[name] && this[name].apply(this, [].slice.call(arguments, 1));
},
};
// mylib.test.js
jest.mock('./mylib.js');
var myLib = require('./mylib.js');
test('', () => {
myLib.execute('requestInfo', 'Ferrari', '14523');
expect(myLib.execute.mock.calls.length).toBe(1); // Success!
expect(myLib.requestInfo.mock.calls.length).toBe(1); // FAIL
});
如果我明确呼叫myLib.requestInfo
,则第二个期望成功。
是否有办法监视通过apply
或call
调用了函数的模块模拟调用?
答案 0 :(得分:2)
来自jest.mock
doc:
在需要时使用自动模拟的版本对模块进行模拟。
可以通过更好地描述“自动模拟版本”的含义来改进文档,但是发生的事情是Jest
保持模块的API表面相同,同时用空的{{ 3}}。
因此,在这种情况下,execute
被调用,但是它已被空的模拟函数代替,因此requestInfo
从未被调用,这会导致测试失败。
要使execute
的实现保持完整,您将要避免自动模拟整个模块,而是使用mock functions之类的东西监视原始功能:
var myLib = require('./mylib.js');
test('', () => {
jest.spyOn(myLib, 'execute'); // spy on execute
jest.spyOn(myLib, 'requestInfo') // spy on requestInfo...
.mockImplementation(() => {}); // ...and optionally replace the implementation
myLib.execute('requestInfo', 'Ferrari', '14523');
expect(myLib.execute.mock.calls.length).toBe(1); // SUCCESS
expect(myLib.requestInfo.mock.calls.length).toBe(1); // SUCCESS
});