How to test that an inner function has been called from an imported function? (with Jest.js)

老子叫甜甜 提交于 2021-02-09 10:58:32

问题


I'm having issues with Jest testing that a closure (an inner function) has been called after calling the outer function. I've tried using the spyOn with no positive result. This seems to be a relatively simple problem, to which I haven't found any results from googling.

// helper.js
export const bar = () => {}
export const foo = () => {
  bar(); //How do I test that this has been called?
}


//helper.test.js
import * as H from 'helper';

const barSpy = jest.spyOn(H, 'bar');
H.foo();

expect(barSpy).toHaveBeenCalled(); // Jest throws error "Expected mock function to have been called." 

回答1:


I had the same issue once, and found this article which is very well explained: https://www.exratione.com/2015/12/es6-use-of-import-property-from-module-is-not-a-great-plan/

From the article:

Stubbing a function in Javascript requires the function to be bound to a context, any context, that is in scope for both the test code and the code being tested. In a sane world this context is provided by the module. For example, in ES5 Node.js:

exports.fn = function () {}

The thing to avoid doing in ES5 is the following, overriding module.exports with a function. All too many people do this and it is inconsiderate, as any module using that code must then take extra steps to be usefully unit tested:

module.exports = function () {}

So the last exported function can't be stubbed since it's not bound to any context, theres a workaraound for that, bounding the function to the exports object of the module you are testing and calling it as exports.importedFunction, like so:

var example = require('./example');

// Exported for test purposes. If we don't do this, then
// example is encapsulated here and cannot be stubbed.
exports.example = example;

// Usage.
exports.invokeExample = function () {
   return exports.example();
};

Then you'll be able to spy on it, but you had to write that extra code, which is kinda ugly and not very useful neither clear.

In ES6 using "import { x } from 'y'" is analogous to overwriting module.exports with a function in ES5. The result is that an imported function is encapsulated in the module and cannot be stubbed in unit tests without writing more boilerplate code that would otherwise have been the case.

This also happens for your case: import * as H from 'helper'



来源:https://stackoverflow.com/questions/48756241/how-to-test-that-an-inner-function-has-been-called-from-an-imported-function-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!