jun*_*cia 1 javascript unit-testing mocking jestjs
How can I use mocks to count function calls made via call or 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));
},
};
Run Code Online (Sandbox Code Playgroud)
// 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
});
Run Code Online (Sandbox Code Playgroud)
If I explicitly call myLib.requestInfo, the second expectation succeeds.
Is there a way to watch module mock calls whose functions were called via apply or call?
从jest.mock 文档:
在需要时使用自动模拟版本模拟模块。
可以通过更好地描述“自动模拟版本”的含义来改进文档,但发生的情况是Jest在用空模拟函数替换实现的同时保持模块的 API 表面相同。
所以在这种情况下execute被调用,但它已被一个空的模拟函数取代,所以requestInfo永远不会被调用,这会导致测试失败。
为了保持execute完整的实现,您将希望避免自动模拟整个模块,而是使用以下内容监视原始函数jest.spyOn:
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
});
Run Code Online (Sandbox Code Playgroud)