Rackアプリケーションをテストするときの話です。
Predicate Matchersってなんじゃらホイ
[].empty? # -> true
it { [].should be_empty }
be_{predicate}
で obj.{predicate}?
を呼ぶRSpecの便利マッチャ。
これのお陰で [].count.should eq 0
みたいなのを書かずに済む。
Predicate Matchersに足を向けて寝れない!!!!!
ステータス・コードをテストするときにもPredicate Matchers
describe "GET", "/" do
subject { last_response }
before { get '/' }
it { should be_ok }
end
だいたいこんなかんじでステータスコードをテストする。
しかし、テストが失敗すると非常に悲しい。
Failures:
1) RootController GET /
Failure/Error: it { should be_ok } expected ok? to return true, got false # ./spec/app/controllers/root_controller_spec.rb:38:in `block (4 levels) in <top (required)>'
Finished in 0.5261 seconds
3 examples, 1 failure
こんなかんじのFailure Messageがっっっ。
意図せずテストが失敗したとき、Failure Messageなどを頼りにテストやプロダクトコードを直すわけですが、これでは200が返らなかったことしかわからないので不便。
should
にCustom Failure Messageを渡す
describe "GET", "/" do
# ...
it { should be_ok, "Actual status: #{last_response.status}" }
end
第二引数に失敗したときに出力されるメッセージを渡すことができるのでこれを使ってみる。
Failures:
1) RootController GET /
Failure/Error: it { should be_ok, last_response.status }
Actual status: 1
# ./spec/app/controllers/root_controller_spec.rb:38:in `block (4 levels) in <top (required)>'
Finished in 0.58836 seconds3 examples, 1 failure
ずっと親切!!!!!
ちなみにこれは本当に出くわした失敗で、Sinatra/Padrinoではアクションの返り値がIntegerだとHTTP ステータスコードと解釈してRack::Responseに設定するのでした、こわいですね。