0

and_return引数が一種の例外である場合に例外を発生させるようにメソッドを拡張したい。例えば

obj.stub(:meth).and_return(SomeException,"message")

この構成では、最初の呼び出しで例外が発生し、2 回目の呼び出しで文字列が返されます。

この方法で rspec を拡張する方法、そのようなタスクのガイドラインはありますか?

アップデート:

この関数の一般的な表記法は次のとおりです。

and_return_or_raise(list of arguments or/and exceptions)
4

3 に答える 3

1

どうですか

stuff = [SomeException, "message"]
obj.stub(:meth).and_return do
  i = stuff.shift
  if i.respond_to?(:downcase)
    i
  else
    raise i
  end
end    

確かに最も美しい方法ではありませんが、特定の場合にその仕事をする必要があります。

于 2013-01-08T15:24:37.007 に答える
1

したがって、複数の値を返す実際の作業は、クラスの次のメソッドにあります。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
于 2013-01-08T17:20:39.760 に答える
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
于 2013-01-08T17:23:40.883 に答える