如果参数是一种异常,我想扩展and_return
方法以引发异常。例如
obj.stub(:meth).and_return(SomeException,"message")
这种构造应该在第一次调用时引发异常,并在第二次调用时返回字符串。
如何通过这种方法扩展 rspec,是否有此类任务的指南?
更新:
此函数的一般表示法可以是:
and_return_or_raise(list of arguments or/and exceptions)
怎么样
stuff = [SomeException, "message"]
obj.stub(:meth).and_return do
i = stuff.shift
if i.respond_to?(:downcase)
i
else
raise i
end
end
当然不是最漂亮的方式,但应该在您的特定情况下完成这项工作。
所以,返回多个值的实际业务是在类中的这个方法中RSpec::Mocks::MessageExpectation
:
def call_implementation_consecutive(*args, &block)
@value ||= call_implementation(*args, &block)
@value[[@actual_received_count, @value.size-1].min]
end
基本上,call_implementation
返回您传递给的预期返回值列表and_return
,并且此方法挑选出与当前调用相对应的那个(如果我们调用该方法的次数多于列表中的值,则返回最后一个值)。
所以,要做你想做的事,你可以猴子修补这个方法,如下所示:
class RSpec::Mocks::MessageExpectation
alias_method :old_call_implementation_consecutive, :call_implementation_consecutive
def call_implementation_consecutive(*args, &block)
old_call_implementation_consecutive(*args, &block).tap do |value|
raise value if value.is_a?(Class) && value < Exception
end
end
end
你不需要扩展任何东西——只需使用 RSpec 的内置错误匹配器并接收计数:
class Foobar
def foo
bar
end
end
it "raises the first time, then returns a string" do
obj = Foobar.new
obj.should_receive(:bar).once.and_raise(StandardError)
obj.should_receive(:bar).once.and_return("message")
expect { obj.foo }.to raise_error(StandardError)
obj.foo.should == "message"
end