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

IT技术 javascript reactjs unit-testing jestjs
2021-04-29 16:20:29

我在测试调用外部函数后调用了闭包(内部函数)时遇到了问题。我试过使用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个回答

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

从文章:

在 Javascript 中存根函数需要将函数绑定到上下文,任何上下文都在测试代码和被测试代码的范围内。在一个理智的世界里,这个上下文是由module提供的。例如,在 ES5 Node.js 中:

exports.fn = function () {}

在 ES5 中避免做的事情如下,用一个函数覆盖 module.exports。太多人这样做了,这是不体贴的,因为任何使用该代码的module都必须采取额外的步骤才能进行有效的单元测试:

module.exports = function () {}

所以最后一个导出的函数不能被存根,因为它没有绑定到任何上下文,有一个解决方法,将函数绑定到您正在测试的module的导出对象并将其调用为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 中使用 "import { x } from 'y'" 类似于在 ES5 中使用函数覆盖 module.exports。结果是导入的函数被封装在module中,并且不能在单元测试中存根,除非编写更多的样板代码,否则会出现这种情况。

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