RSpec:如何在实例化之前对对象的方法进行存根,而不必存根所有其余部分?
RSpec: How can I stub a method on an object, before instantiation, without having to stub all the rest?
我正在为 Rails 编写 gem,其中包括用于创建模型的生成器。在某些情况下,生成器应该调用自己,它使用 generate
方法来执行此操作。实际使用时效果很好
我正在使用 RSpec 3.2 和 generator_spec
来尝试测试此功能,但是作为 gem,当它到达 generate
调用时,它会抱怨Rails 不存在:
/path/to/ruby: No such file or directory -- bin/rails (LoadError)
所以我一直在尝试对 Generator#generate
方法进行存根处理,使其与规范中的 run_generator
做同样的事情,紧接在调用 [=15] 的 run_generator
调用之前=] 在他们中间。
但是,对于我所有可能的解决方案,我遇到了 运行 个问题。
完全覆盖 class - 无法使用规范方法。
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
不会还存在。
使用双实例 - 不允许使用其他方法。
recursible = instance_double(Generator)
allow(recursible).to receive(:generate) { |*args| run_generator args[1..-1] }
test_case_instance.generator_class = recursible
但是,使用 double 需要您存根 所有 上面将要使用的方法 - 其余所有方法都将简单地调用它们的原始实现。这似乎很困难而且没有必要。有什么办法绕过它吗?
Taryn East ended up giving me the :我的测试目录中需要一个成熟的 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
我正在为 Rails 编写 gem,其中包括用于创建模型的生成器。在某些情况下,生成器应该调用自己,它使用 generate
方法来执行此操作。实际使用时效果很好
我正在使用 RSpec 3.2 和 generator_spec
来尝试测试此功能,但是作为 gem,当它到达 generate
调用时,它会抱怨Rails 不存在:
/path/to/ruby: No such file or directory -- bin/rails (LoadError)
所以我一直在尝试对 Generator#generate
方法进行存根处理,使其与规范中的 run_generator
做同样的事情,紧接在调用 [=15] 的 run_generator
调用之前=] 在他们中间。
但是,对于我所有可能的解决方案,我遇到了 运行 个问题。
完全覆盖 class - 无法使用规范方法。
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
不会还存在。
使用双实例 - 不允许使用其他方法。
recursible = instance_double(Generator)
allow(recursible).to receive(:generate) { |*args| run_generator args[1..-1] }
test_case_instance.generator_class = recursible
但是,使用 double 需要您存根 所有 上面将要使用的方法 - 其余所有方法都将简单地调用它们的原始实现。这似乎很困难而且没有必要。有什么办法绕过它吗?
Taryn East ended up giving me the
不幸的是,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