RSpecではbeforeの中で例外を起こすとどうなるの?
Baconさんをどう直すべきかを考えるにあたって、まず気になるのは、RSpecではbeforeの中で例外が起きた時にどうなるの?ということです。beforeで例外が起きた時にはafterを呼ぶべきなのでしょうか。beforeで失敗してるんだからafter呼び出しても無駄じゃない?とは思うのですが、それでもやっぱりafterを呼ぶのでしょうか。試してみました。
describe "exception at before" do before do puts "*** before ***" raise StandardError end after do puts "*** after ***" end it "should be true" do true.should be_true end end
これを実行すると次のような結果になりました。
*** before *** *** after *** F 1) StandardError in 'exception at before should be true' StandardError ./test.rb:4: Finished in 0.945952 seconds 1 example, 1 failure
これにより、afterが呼び出されているのが分かりました。実際的な場面を考えればbeforeで失敗している以上たぶんafterも思った通りにならないのだろうとは思いますが、そうであったら別に呼ぼうが呼ぶまいがどっちでも良いわけで、それだったら一応afterを呼び出しておいた方がやっぱり無難でお得感があるのかな、と思いました。つまり、RSpecは素晴しいということです。
ていうか、Ramazeさんが素直にRSpec使っていてくれればこんなことに悩まなくていいのに、などとちょびっと愚痴をこぼしたくなる今日この頃です。Ramaze + Sequel + Bacon って、マイナー路線まっしぐらですよね。
追記
そういえばbeforeで失敗した時ってテスト毎回呼び出すのかな?と疑問に思ったのでやってみました。
describe "exception at before" do before do puts "*** before ***" raise StandardError end after do puts "*** after ***" end it "1" do true.should be_true end it "2" do true.should be_true end it "3" do true.should be_true end end
で実行すると。
*** before *** *** after *** F*** before *** *** after *** F*** before *** *** after *** F 1) StandardError in 'exception at before 1' StandardError ./test.rb:4: 2) StandardError in 'exception at before 2' StandardError ./test.rb:4: 3) StandardError in 'exception at before 3' StandardError ./test.rb:4: Finished in 0.194704 seconds 3 examples, 3 failures
というわけで、beforeが失敗してもちゃんと 1, 2, 3 がそれぞれ呼ばれました。でも普通、before(:each)が失敗する時には各々が失敗するのは明らかなんじゃないのかな?と思うわけです。before(:each)が成功したり失敗したり変動する状況というのもあまり考えられないのでどうなんだろうかと思います。beforeにネットワーク依存なコードを書いちゃった場合とかなら意味があるのかなぁ、と思いますが、どうかな。beforeが失敗したらafter呼んで即座にテストを終了しても良いような気がします。