RSpec:在实例化之前,如何在对象上存根一个方法,而不必存根所有其余的方法?

RSpec:在实例化之前,如何在对象上存根一个方法,而不必存根所有其余的方法?,rspec,gem,mocking,Rspec,Gem,Mocking,我正在为Rails编写一个gem,其中包括一个用于创建模型的生成器。在某些情况下,生成器应该调用自己,并使用generate方法来实现这一点。这在实际使用时效果很好 我正在使用RSpec 3.2和generator_spec来尝试和测试此功能,但作为一个gem,当它到达generate调用时,它会抱怨Rails不存在: /path/to/ruby: No such file or directory -- bin/rails (LoadError) p>所以我一直在尝试生成发电机生成方法,使

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

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

/path/to/ruby: No such file or directory -- bin/rails (LoadError)
<> p>所以我一直在尝试生成发电机生成方法,使它在规范中运行Runx生成器,在RuniGuver调用中间调用生成之前。 然而,对于所有可能的解决方案,我都遇到了问题

直接重写类-无法使用spec方法。 这将引发未定义的方法“run_generator”。不足为奇

使用部分双实例化太晚了。 这将是完美的,但是run_生成器在幕后调用一个类方法,因此所讨论的生成器还不存在

使用双实例-不允许使用其他方法。 但是,使用double需要存根它上所有将要使用的方法,其余的方法只需调用它们的原始实现即可。这似乎既困难又没有必要。有什么办法可以绕过它吗?

最终给了我一个答案:我需要在我的测试目录中安装一个完整的Rails应用程序

不幸的是,generator_spec的prepare_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

您是否尝试过:允许生成程序的任何实例接收:生成…@TarynEast!但是现在我得到了rspec uu generate u,而没有任何u实例uu接受-2参数,但它不应该。好的,所以存根应该完全覆盖一个方法,并用简单的返回值替换它。。。当您传递正确的参数时。。。这意味着您确实需要将参数传递给它,在本例中,我只是用。。。但是你应该有类似的东西。使用arg1,arg2,不管你期望的参数是什么,然后你应该返回一个返回值。。。然而如果您实际上正试图在存根中运行代码。。。那你可能用错了。。也许还有另一种方法可以做到这一点。你在谷歌上搜索过关于如何测试rails gems的教程吗?我认为他们倾向于在测试目录中包含完整的迷你应用程序…我有一种感觉,run_generator调用实际上是在链的某个地方生成的,不知怎么的。。。
allow(generator).to receive(:generate) { |*args| run_generator args[1..-1] }
recursible = instance_double(Generator)
allow(recursible).to receive(:generate) { |*args| run_generator args[1..-1] }
test_case_instance.generator_class = recursible
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