【问题标题】:How to mock a method from a helper in RSpec如何从 RSpec 中的助手模拟方法
【发布时间】:2017-06-27 06:45:21
【问题描述】:

考虑在 gem 中使用的以下代码,它是我们主应用程序的依赖项:

module Module1
  module Module2
    module EnvInit
      def stub_env(name, value)
        stub_const('ENV', ENV.to_hash.merge(name => value))
      end
    end
  end
end

RSpec.configure do |config|
  config.include Module1::Module2::EnvInit
  config.before(:each) do
    stub_env('NAME', 'John Doe')
  end
end

我们的主应用程序使用 .env 文件作为我们的环境变量。但是,上面的代码出于某种原因覆盖了ENV['NAME']。我们无权访问这个 gem,所以为了让我们的测试持续下去,我想在调用 stub_env 时进行模拟,如下所示:

before do
  # tried this with `allow_any_instance_of` as well
  allow(Module1::Module2::EnvInit).to receive(:stub_env).with('NAME','John Wayne')
end

it "should match name to John Wayne" do
  EnvInit.any_instance.should_receive(:stub_env).with('NAME','John Wayne')
end

等等。我尝试了各种模拟方式,但我以stub_env 为目标的尝试都没有奏效。所有stub_env 看到的是John Doe

简单地说,我希望stub_env 通过模拟接收value == John Wayne

【问题讨论】:

  • RSpec.configure 部分可能来自 gem 的一个规范文件。您不应该在您的应用程序中包含这些文件。如果包含 gem 会自动添加 gem 的测试设置,这是一个严重的错误,应该修复。

标签: ruby-on-rails ruby unit-testing rspec


【解决方案1】:

模拟是将默认行为更改为您想要的行为的过程。也就是说,你想模拟stub_env接收John Doe(因为它在现实生活中接收"John Doe")并把"John Wayne"放在ENV中。

allow_any_instance_of(Module1::Module2::EnvInit).to \
  receive(:stub_env).
    with('NAME', 'John Doe').
    and_return stub_const('ENV', ENV.to_hash.merge('NAME => 'John Wayne'))

【讨论】:

  • 我刚才试过了,但没有骰子。您似乎返回了相同的 stub_const 行以及我想要保留的值(John Wayne),并且另一个更改是通过 with() 提供给硬编码的值。仍然无法针对有问题的方法。
  • 不能嘲笑来电者。可以模拟被调用者。另外,我不明白为什么上述方法对你不起作用。
  • 对我来说,理想的解决方案是将 binding.pry 放在第 5 行,就在 stub_const('ENV', ENV.to_hash.merge(name => value)) 之前,并且 value 返回 John Wayne。根据您的建议,value==John Doe。如果我exit,我的测试失败。感谢您调查它。我期待着明天第一件事回到这个对话。
猜你喜欢
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 2013-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-17
相关资源
最近更新 更多