我在这里看到过关于嘲笑默认导出的问题,但我不认为这已经被问到了:
当模拟正在测试的模块的依赖项的默认导出时,如果模块使用ES6 import语句导入依赖项,则测试套件将无法运行,声明TypeError: (0 , _dependency.default) is not a function
。
在我的理解中,import module from location
直接转换为const module = require(location).default
,所以我非常困惑为什么会发生这种情况。我宁愿保持代码风格一致,而不是在原始模块中使用require
调用。
有办法吗?
模拟测试文件:
import './modules.js';
import dependency from './dependency';
jest.mock('./dependency', () => {
return {
default: jest.fn()
};
});
// This is what I would eventually like to call
it('calls the mocked function', () => {
expect(dependency).toHaveBeenCalled();
});
Dependency.js
export default () => console.log('do something');
module.js(不工作)
import dependency from './dependency.js';
dependency();
module.js(工作)
const dependency = require('./dependency.js').default;
dependency();
4条答案
按热度按时间qgzx9mmu1#
您可以使用
es6 import
或require js
在jest测试中导入js文件。在使用
es6 import
时,你应该知道jest正在尝试解析所有的依赖项,并且还会调用你要导入的类的构造函数。在这一步中,你不能mock它。依赖项必须成功解析,然后你才能继续进行mock。我还应该补充一点,正如在这里可以看到的,jest默认情况下将所有jest.mocks提升到文件的顶部,因此放置导入的顺序并不重要。
但是你的问题是不同的,你的mock函数假设你已经使用
require js
包含了js文件。使用
require js
导入文件时,它的结构如下:因此,假设我已经使用
require js
导入了名为“Test”的类,并且它有一个名为“doSomething”的方法,我可以在测试中通过执行以下操作来调用它:当使用
es6 import
导入它时,您应该以不同的方式进行。使用相同的示例:编辑:如果你想使用
es6 import
,请将mock函数改为:o7jaxewo2#
如果您想使用
import dependency from 'dependency'
,请参阅ES模块简短答案nlejzf6q3#
你试过这样的东西吗?我一直在处理默认导出模拟几个月,直到我发现了这个。
这行代码背后的想法是,您导出的模块是一个函数。因此,您需要让Jest知道它必须将所有
./dependency
文件模拟为一个函数,该函数返回jest.fn()
。d6kp6zgx4#
我不得不这样做在vue和jest:
尽管在代码中我使用了默认的导入,但在单元测试中我必须这样命名导入:
然后我使用奇怪的属性'__esModule'来允许jest像这样使用默认构造函数:
最后,在我的单元测试中,我使用了带有实现的spy on default constructor:
成功了,也是唯一成功的方法