如何验证Foobar#some_method
是否占用了一个块。与Foobar.new.respond_to?(:some_method)
class Foobar
def some_method
yield
end
end
为什么吗
这对测试合同界面很有用。确保方法I stub具有未更改的API。
我尝试过的方式
mth = Foobar.new.method(:some_method)
mth.parameters
这将返回一个参数列表(Rspec基本上使用了什么)。如果我有一个像这样的块参数,它就可以工作:
def some_method(&blk)
end
但是,如果某个方法使用yield
,我就不会从#parameters
获得任何内容。
这是为了确保与丑陋的外部世界的接口添加规范。所以我知道如何使用方法。但如果有API更改,我希望规格失败。
答案 0 :(得分:3)
如何验证
Foobar#some_method
是否需要阻止。
ruby中的每个方法都需要(可以)一个块。它可能只是选择不屈服。那么你需要检查的是,我认为:如果方法产生与否。
RSpec有许多收益预期:https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/yield-matchers
RSpec.describe "yield_control matcher" do
specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control }
specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_control }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.twice }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.exactly(2).times }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_least(1) }
specify { expect { |b| MyClass.yield_twice_with(1, &b) }.to yield_control.at_most(3).times }
end
所以对于你的情况,它应该是这样的:
expect{ foobar.some_method }.to yield_control