最近の RSpec 情勢
よしみさんの http://d.hatena.ne.jp/walf443/20070324/1174702913 の記事の補足。
最近のバージョンでは Matchers を自分で追加して should のあとに書ける語を増やします。というかそれを実現するために should とそれを受けるプロキシに分離し、あの賛否が分かれる文型になったわけです。わたしゃいい加減なれてきましたが、確かに前の方が好きだったという思いは消えません:p。
カスタム Matchers の作り方
で、こちらを見るとカスタム Matchers の作り方が解説してあります。
http://rspec.rubyforge.org/rdoc/classes/Spec/Matchers.html
重要なところを(文が通るように加工した上で)コピペすると、こんな感じになります。
module CustomGameMather class BeInZone def initialize(expected) @expected = expected end # ここがキモですね。 def matches?(actual) @actual = actual bob.current_zone.eql?(Zone.new(@expected)) end def failure_message "expected #{@actual.inspect} to be in Zone #{@expected}" end def negative_failure_message "expected #{@actual.inspect} not to be in Zone #{@expected}" end end def be_in_zone(expected) BeInZone.new(expected) end end
で
context "Player behaviour" do include CustomGameMatchers ... specify do bob.should be_in_zone("4") end specify do bob.should_not be_in_zone("3") end end
なるほど。
語彙がたりなくなる?
主に Rails で。
わたしの場合、RSpec on Rails を使っていてもあんまり語彙が足りないなぁ、ということはないです。
というのも、検証したい状態はそれを問い合わせるメソッドをモデルに追加する*1ことがほとんどというコーディングスタイルにしているため、上記の例でいえば
class Player def in_zone?(zone_number) bob.current_zone.eql? Zone.new(zone_number) end end
とかをモデル側に定義しちゃいます。
あとは
@player.should be(:in_zone, "4")
でOK。
rbehaveとかもあるらしい。
で、こういうのが欲しくなるのはインテグレーションテストを書きたい場合*2にきっといろいろ定義したくなるだろうなぁ、と言う気がしてます。
そこで出ているのがこのあいだの勉強会でレオさんがおっしゃっていたrbehave見たいな感じで動きがあるらしいです。
きのう、ちょっとうちのボスと話した感じでは、rbehaveはユーザストーリーなどのより大きな単位で記述できるのを目的としてるようです。しばらく活動が止まってたみたいなんですが、そこをうまくRSpec(単体テストの粒度、ボトムアップ用ですね)と組み合わせられないか、というのでいろいろ再開し始めてるのが最近の動きらしいです。
このへん、追っかけてる人や開発陣の英語ブログを苦もなく読み下せる人の解説プリーズ。