如何测试从导入的函数调用内部函数? (与Jest.js)

时间:2018-02-12 22:01:37

标签: javascript reactjs unit-testing jestjs

我遇到Jest测试问题,在调用外部函数后调用了一个闭包(内部函数)。我尝试使用spyOn但未获得正面结果。这似乎是一个相对简单的问题,我没有通过谷歌搜索找到任何结果。

// 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 个答案:

答案 0 :(得分:0)

我曾经遇到过同样的问题,并且发现这篇文章得到了很好的解释:https://www.exratione.com/2015/12/es6-use-of-import-property-from-module-is-not-a-great-plan/

来自文章:

  

在Javascript中对函数进行存储需要将函数绑定到上下文,任何上下文,这些上下文都在测试代码和正在测试的代码的范围内。在一个理智的世界中,该环境由模块提供。例如,在ES5 Node.js中:

     

exports.fn = function () {}

     

要避免在ES5中执行的操作如下,请使用函数覆盖module.exports。所有太多的人都会这样做,而且不重要,因为任何使用该代码的模块都必须采取额外的步骤才能进行有效的单元测试:

     

module.exports = function () {}

因此,最后导出的函数不能被存根,因为它没有绑定到任何上下文,这是一个可行的工作方式,将函数绑定到您正在测试的模块的exports对象并将其称为exports.importedFunction,如此:

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();
};

然后你就可以窥探它了,但是你必须编写那些额外的代码,这有点难看,也不是很有用。

  

在ES6中使用"导入{x}来自''"类似于在ES5中覆盖带有函数的module.exports。结果是导入的函数被封装在模块中,并且在没有编写更多样板代码的情况下不能在单元测试中存根。

这也适用于您的情况:import * as H from 'helper'