【问题标题】:RSpec: How can I stub a method on an object, before instantiation, without having to stub all the rest?RSpec:如何在实例化之前对对象的方法进行存根,而不必对所有其余部分进行存根?
【发布时间】:2015-04-28 00:27:58
【问题描述】:

我正在为 Rails 编写一个 gem,其中包括一个用于创建模型的生成器。在某些情况下,生成器应该调用自己,它使用generate 方法来执行此操作。实际使用时效果很好。

我正在使用带有generator_spec 的 RSpec 3.2 来尝试测试此功能,但作为一个 gem,当它到达 generate 调用时,它抱怨 Rails 不存在:

/path/to/ruby: No such file or directory -- bin/rails (LoadError)

所以我一直在尝试对Generator#generate 方法进行存根,使其在规范中与run_generator 执行相同的操作,紧接在它们中间调用generaterun_generator 调用之前。 但是,对于我所有可能的解决方案,我都遇到了问题。

直接覆盖类 - 不能使用规范方法。

class Generator
  def generate(*args)
    run_generator args[1..-1]
  end
end

这引发了undefined method 'run_generator'。不足为奇。

使用部分双精度实例化太晚了。

allow(generator).to receive(:generate) { |*args| run_generator args[1..-1] }

这将是完美的,但 run_generator 在后台调用了一个 class 方法,因此所讨论的 generator 尚不存在。

使用实例 double - 不允许使用其他方法。

recursible = instance_double(Generator)
allow(recursible).to receive(:generate) { |*args| run_generator args[1..-1] }
test_case_instance.generator_class = recursible

但是,使用 double 需要您将要使用的方法存根 所有 - 而所有其他方法都只是调用它们的原始实现。这似乎是困难和不必要的。有什么办法可以绕过去吗?

【问题讨论】:

  • 你试过了吗:allow_any_instance_of(Generator).to receive(:generate) ...
  • @TarynEast 有前途!但现在我收到了rspec __generate_without_any_instance__ takes -2 argument, but it should not.
  • 好的,所以存根应该完全覆盖一个方法并用简单的返回值替换它......当你传递正确的参数时......这意味着你确实需要将参数传递给它(在这种情况下,我只是用... 抽象多佛尔,但你应该有类似.with(arg1, arg2) 的东西(无论你期望的参数是什么)然后你应该返回一个返回值......但是......如果你实际上是在尝试在存根中运行代码......那么你可能将它用于错误的目的......并且可能还有另一种方式你应该这样做。
  • 您是否在 Google 上搜索过有关如何测试作为 rails gem 的 gem 的教程?我认为他们倾向于在测试目录中包含完整的迷你应用程序......
  • 我感觉run_generator 实际上调用 generate 在链条的某个地方,不知何故...

标签: rspec gem mocking


【解决方案1】:

Taryn East 最终给了我vital clue:我需要一个完整的 Rails 应用程序在我的测试目录中。

不幸的是,generator_specprepare_destination 方法完全炸毁了目标目录,所以这就是我的结果:

it 'the test' do
  system "rails new #{destination_root} -Bfq" # no bundling, force overwrite, quiet
  File.write "#{destination_root}/Gemfile", "gem '#{File.basename Dir.pwd}', path: '#{Dir.pwd}'", mode: 'a'
  system "cd #{destination_root} && bundle install --quiet"

  # ... continue with the test as before

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 2010-12-25
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多