草庐IT

javascript - 开 Jest 模拟默认导出 - 需要与导入

coder 2024-07-24 原文

我在这里看到了一些关于用 jest 模拟默认导出的问题,但我认为还没有人问过这个问题:

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

在我的理解中,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();
});

依赖.js

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

module.js(不工作)

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

module.js(工作)

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

最佳答案

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

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

我还应该补充一点,可以看出here默认情况下,jest 将任何 jest.mocks 提升到文件的顶部,因此放置导入的顺序并不重要。

但您的问题有所不同。您的模拟函数假定您已经使用 require js 包含了您的 js 文件。

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

当您使用 require js 导入文件时,这是它的结构:

所以假设我已经使用 require js 导入了名为“Test”的类,并且它有一个名为“doSomething”的方法,我可以在我的测试中调用它,方法如下:

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

当使用 es6 import 导入它时,您应该以不同的方式进行。使用相同的示例:

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

编辑:如果您想使用 es6 import 将模拟函数更改为:

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

关于javascript - 开 Jest 模拟默认导出 - 需要与导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47056694/

有关javascript - 开 Jest 模拟默认导出 - 需要与导入的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  3. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  4. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  5. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  6. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  7. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  8. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  9. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

  10. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

随机推荐