开玩笑的默认导出 - 需要与导入 [英] Jest mocking default exports - require vs import

查看:23
本文介绍了开玩笑的默认导出 - 需要与导入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里看到过一些关于嘲笑默认导出的问题,但我不认为已经有人问过这个问题:

模拟正在测试的模块的依赖项的默认导出时,如果模块使用 ES6 导入语句导入依赖项,则测试套件将无法运行,说明 TypeError: (0 , _dependency.default)不是函数 但是,如果模块使用 require().default 调用代替,它会成功.

在我的理解中,import module from location 直接转化为const module = require(location).default,所以我很困惑为什么会发生这种情况.我宁愿保持我的代码风格一致,而不是在原始模块中使用 require 调用.

有办法吗?

使用模拟测试文件:

import './modules.js';从'./dependency'导入依赖;jest.mock('./dependency', () => {返回 {默认值:jest.fn()};});//这就是我最终想要调用的it('调用模拟函数', () => {期望(依赖).toHaveBeenCalled();});

依赖.js

export default () =>console.log('做某事');

module.js(不工作)

从'./dependency.js'导入依赖;依赖();

module.js(工作)

const dependency = require('./dependency.js').default;依赖();

解决方案

你可以使用 es6 importrequire js 在你的 jest 测试中导入你的 js 文件.

在使用 es6 import 时,您应该知道 jest 正在尝试解析所有依赖项,并且还为您正在导入的类调用构造函数.在此步骤中,您不能模拟它.必须成功解决依赖关系,然后您才能继续进行模拟.

我还应该补充一点,可以看出

因此,假设我使用 require js 导入了名为Test"的类,并且它具有名为doSomething"的方法,我可以通过执行以下操作在我的测试中调用它:

const test = require('../Test');test.default.doSomething();

当使用 es6 import 导入它时,你应该做不同的事情.使用相同的示例:

从'../Test'导入测试;测试.doSomething();

如果您想使用 es6 import 将您的模拟功能更改为:

jest.mock('./dependecy', () => jest.fn());

I have seen questions referring to the mocking of default exports with jest around here, but I don't think this has already been asked:

When mocking the default export of a dependency of a module that is being tested, the tests suite fails to run if the module imports the dependency with the ES6 import statement, stating TypeError: (0 , _dependency.default) is not a function It succeeds, however, if the module uses a require().default call instead.

In my understanding, import module from location directly translates to const module = require(location).default, so I am very confused why this is happening. I'd rather keep my code style consistent and not use the require call in the original module.

Is there a way to do it?

Test file with mock:

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 (not working)

import dependency from './dependency.js';
dependency();

module.js (working)

const dependency = require('./dependency.js').default;
dependency();

解决方案

You can use either es6 import or require js to import your js files in your jest tests.

When using es6 import you should know that jest is trying to resolve all the dependencies and also calls the constructor for the class that you are importing. During this step, you cannot mock it. The dependency has to be successfully resolved, and then you can proceed with mocks.

I should also add that as can be seen here jest by default hoists any jest.mocks to the top of the file so the order in which you place your imports does not really matter.

Your problem though is different. Your mock function assumes that you have included your js file using require js.

jest.mock('./dependecy', () => {
   return {
      default: jest.fn()
   };
});

When you import a file using require js, this is the structure it has:

So assuming I have imported my class called "Test" using require js, and it has method called "doSomething" I could call it in my test by doing something like:

const test = require('../Test');
test.default.doSomething();

When importing it using es6 import, you should do it differently though. Using the same example:

import Test from '../Test';
Test.doSomething();

EDIT: If you want to use es6 import change your mock function to:

jest.mock('./dependecy', () => jest.fn());

这篇关于开玩笑的默认导出 - 需要与导入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆