RSpecを使ったテストコードを読もうRailsコードリーディング〜scaffoldのその先へ〜(2)(3/4 ページ)

» 2008年11月26日 00時00分 公開
[倉貫義人、松村章弘TIS株式会社/SonicGarden]

モデルのスペックを読んでみよう

 では、SKIPのグループ機能のモデル部分を使って、スペックのコードリーディングをしていきましょう。

 今回、イメージをつかむためにも、シンプルなメソッドを選びます。Groupモデルのhas_waitingというメソッドです。ファイルの場所はapp/models/group.rbになります。このメソッドは、前述の承認制の仕様で、グループに対して「参加承認待ち」のユーザーがいるかどうかを判定するために使われます。

77 def has_waiting
78 if group_participations.find(:all, :conditions =>["waiting = ?", true]).size > 0
79 return true
80 end
81 return false
82 end
   app/models/group.rb 77-82

 非常に簡単ですね。グループ参加状況(group_participation)に、承認待ち(waiting)でデータがあれば、承認待ちのユーザーがいる、というわけです(1行でも書けますが、今回はあえて分岐で表現しています)。

 このメソッドの主なロジックは、78行目のif文です。その結果でメソッドは、trueかfalseを返しています。よって、スペックで確かめたいのは、このif文の条件に応じてメソッドの戻り値が期待どおりに変化することです。

 では、対応するスペックを見てみましょう。ファイルは、spec/models/group_spec.rbになります。Groupモデルなので、対応するスペックは、_specを付けたファイル名になっています。

59 describe Group, "承認待ちのユーザーがいるとき" do  #条件の説明 
60   before(:each) do                                 #条件の状態を作り出す 
61     @group = Group.new
62     @group_participations = [GroupParticipation.new({ :waiting => true })]
63     @group.should_receive(:group_participations).and_return(stub('group_particip
64 ations', :find => @group_participations))
65   end
66   it "has_waitingはtrueを返す" do                  #実施するテストの結果の説明
67     @group.has_waiting.should be_true              #実際に検証している文
68   end
69 end
70 
71 describe Group, "承認待ちのユーザーがいないとき" do
72   before(:each) do
73     @group = Group.new
74     @group_participations = []
75     @group.should_receive(:group_participations).and_return(stub('group_participations', :find => @group_participations))
76   end
77 
78   it "has_waitingはfalseを返す" do
89     @group.has_waiting.should be_false
80   end
81 end
   spec/models/group_spec.rb 59-81

 59行目のdescribeの後の文字列で、これから実施するテストの条件を説明しています。この場合「承認待ちのユーザーがいるとき」という、先ほどのif文が分岐する条件を表しています。

 60〜64行目のbeforeのブロックの中で、「承認待ちのユーザーがいるとき」という条件になるようにメソッドが動作する状態を作り出しています。

 そして、66行目のitの後の文字列で実際に動作すべき結果である「has_waitingはtrueを返す」と記述します。実際にメソッドを動作させて戻り値が正しいかを確認しているのは、itのブロックの中の67行目のshouldというメソッドです。

 71行目から81行目も同様に、テストする条件と結果が変わっていますが、同様の流れになっています。

 スペックでは、基本的にはこのような流れで記述されています。検証すべきロジックが増えるとテストする条件が増えdescribe文の中にもう一段describe文が入るなど複雑性を増しますが、この基本さえ分かっていれば、多少複雑になったとしても、スペックに書かれている内容が理解できるはずです。

 さて、ここであらためてdescribeとitのみに注目して、もう一度スペックを見てください。

59 describe Group, "承認待ちのユーザーがいるとき" do
66   it "has_waitingはtrueを返す" do
71 describe Group, "承認待ちのユーザーがいないとき" do
78   it "has_waitingはfalseを返す" do
   spec/models/group_spec.rb 59,66,71,78

 Groupモデルのメソッドであるhas_waitingの振る舞いが端的に書かれているということに気付けたと思います。このdescribeとitのみの行を切り出してみると、まるでクラスの仕様書のように読めますね。RSpecでは、この内容と同等の結果を出力する機能も用意されています。-cfsオプションを付けて実行すると、以下のように出力されます。

ALT 図5 仕様書風の出力

 ソースコードリーディングを行っていて、挙動が分からないメソッドがあれば、上記の出力を利用してメソッドの仕様を理解するのも一つの手です。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。