如果参数是一种异常,我想扩展and_return
方法以引发异常。
例如
obj.stub(:meth).and_return(SomeException,"message")
这种结构应该在第一次调用时引发异常,并在第二次调用时返回该字符串。
如何通过这种方法扩展rspec,是否有这种任务的指导方针?
更新:
此功能的一般表示法可能是:
and_return_or_raise(list of arguments or/and exceptions)
答案 0 :(得分:1)
怎么样
stuff = [SomeException, "message"]
obj.stub(:meth).and_return do
i = stuff.shift
if i.respond_to?(:downcase)
i
else
raise i
end
end
肯定不是最漂亮的方式,但应该在你的特定情况下做好工作。
答案 1 :(得分:1)
因此,返回多个值的实际业务是RSpec::Mocks::MessageExpectation
类中的this method:
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
答案 2 :(得分:1)
您不需要扩展任何内容 - 只需使用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