rspec-mocks の and_raise で嵌った

rspec-mocks を使って

allow_any_instance_of(User).to receive(:save!).and_raise(ActiveRecord::RecordNotSaved)

という風にモデルの保存に失敗するテストを書いていたけど、 Rails 4.2 に更新したら実際に save! を呼び出すところで ArgumentError が発生するようになって嵌った。

ちなみに gem のバージョンは次の通り。

pry-bybug でステップ実行しつつ調べたら原因判明。 rspec-mocks では、and_raise で指定した例外クラスをスローするとき、 例外クラスの exception メソッドを使ってインスタンスを生成していた。

で、and_raise の引数でメッセージを渡さなかった場合は、引数なしの exception が呼ばれるんだけど、 ActiveRecord::RecordNotFound の exception は引数が必須。 だから ArgumentError が発生してしまっていた。

ひとまず

allow_any_instance_of(User).to receive(:save!).and_raise(ActiveRecord::RecordNotSaved, "error")

という風にメッセージを渡すことで回避に成功。