简体   繁体   English

开玩笑模拟默认导出 - 需要与导入

[英]Jest mocking default exports - require vs import

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:我在这里看到了关于用 jest 模拟默认导出的问题,但我认为这已经被问过了:

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.在模拟正在测试的模块的依赖项的默认导出时,如果模块使用 ES6 导入语句导入依赖项,则测试套件将无法运行,说明TypeError: (0 , _dependency.default) is not a function It succeeds ,但是,如果模块使用require().default调用代替。

In my understanding, import module from location directly translates to const module = require(location).default , so I am very confused why this is happening.据我了解, import module from location直接转换为const module = require(location).default ,所以我很困惑为什么会这样。 I'd rather keep my code style consistent and not use the require call in the original module.我宁愿保持我的代码风格一致,而不是在原始模块中使用require调用。

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依赖.js

export default () => console.log('do something');

module.js (not working) module.js(不工作)

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

module.js (working) module.js(工作)

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. 您可以使用es6 import或者require js在您的jest测试中导入您的js文件。

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. 使用es6 import您应该知道jest正在尝试解析所有依赖项,并且还调用要导入的类的构造函数。 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. 我还应该补充一点, 这里可以看到jest默认情况下将任何jest.mocks提升到文件的顶部,这样放置导入的顺序并不重要。

Your problem though is different. 你的问题虽然不同。 Your mock function assumes that you have included your js file using require js . 您的模拟函数假定您已使用require js包含了js文件。

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

When you import a file using require js , this is the structure it has: 使用require js导入文件时,这是它具有的结构:

在此输入图像描述

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: 因此,假设我使用require js导入了名为“Test”的类,并且它有一个名为“doSomething”的方法,我可以通过执行以下操作在我的测试中调用它:

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

When importing it using es6 import , you should do it differently though. 使用es6 import ,您应该采用不同的方式。 Using the same example: 使用相同的例子:

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

EDIT: If you want to use es6 import change your mock function to: 编辑:如果你想使用es6 import更改您的模拟功能:

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

Have you tried something like this?你有没有尝试过这样的事情? I was dealing with the default export mocking for months until I found this.几个月来,我一直在处理默认导出模拟,直到我发现了这一点。

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

The idea behind this line is that you are exporting a module that is a function.此行背后的想法是您正在导出一个作为函数的模块。 So you need to let Jest knows that it has to mock all your ./dependency file as a function, that returns a jest.fn()所以你需要让 Jest 知道它必须将你所有的./dependency文件模拟为一个函数,它返回一个jest.fn()

the short answer for ES module if you want to use import dependency from 'dependency'如果您想使用import dependency from 'dependency'项,则 ES 模块的简短答案

jest.mock('dependency', () => ({
  ...jest.requireActual('dependency'),
  __esModule: true,
  default: jest.fn(),
}))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM