[#44431] コンストラクタの引数について&インスタンス変数の持ち方について — Akira Hayakawa <ruby@...>

度々オブジェクト指向についての質問ですいません。

17 messages 2008/01/04
[#44433] Re: コンストラクタの引数について&インスタンス変数の持ち方について — Yukihiro Matsumoto <matz@...> 2008/01/04

まつもと ゆきひろです

[#44469] pdf 作成 ライブラリ — "Luiz Aoki" <luizruby@...>

はじめまして、青木ルイスと申します、

14 messages 2008/01/12
[#44479] ファイル出力時のprintについて — m-hatake@... 2008/01/16

畠山と申します。

[#44483] format %g の丸めについて — 山崎雄介 <y-yamasaki@...>

山崎(ゆ)です。

14 messages 2008/01/16

[ruby-list:44449] Re: 他のクラスに依存しているコードのテスト

From: 松田 明 <ronnie@...>
Date: 2008-01-06 18:59:26 UTC
List: ruby-list #44449
こんばんは。松田と申します。

> TDD や BDD の考え方からいくと、テストコード(ス 
> ペックコード)ありきなので、
> 問題ないのかなぁとかとも思ったり…。


これでは本末転倒ですね。
とみたさんの例のようなケースでは、Aクラスのモックオブ 
ジェクトを
作成する方法が一般的なのではないかと思います。
特に Rubyでは動的言語っぷりを生かした魔術的なモッキング 
が楽しめる
ライブラリがいくつか公開されているおかげで、このあたりの問題は
かなりエレガントに解決できるようになっています。

例えば、hoge処理は引数を <hoge>タグで囲んで返す、
fuga処理は引数をreverseして A#hogeして返す、
という仕様を想定してみます。
で、現在のところAとBの実装が以下のようになってい 
たとします。

class A
   def hoge(str)
     #TODO 未実装
   end
end

class B
   def fuga(param)
     a = A.new
     a.hoge(param.reverse)
   end
end

このBのfugaメソッドに対して単体テストコードを記述 
する場合、
例えば RSpecでは以下のように書けます(1個目の  
example)。

describe B do
   before do
     @b = B.new
     @a = mock(A)
     @a.stub!(:hoge).with('aiueo').and_return('<hoge>aiueo</hoge>')
     A.stub!(:new).and_return(@a)
   end

   it "param for fuga() should be reversed and hogenized" do
     @b.fuga('oeuia').should == '<hoge>aiueo</hoge>'
   end

   it "A#hoge should be called inside fuga() once with reversed param"  
do
     @a.should_receive(:hoge).with('ABCDE').once
     @b.fuga('EDCBA')
   end
end


ここでのポイントは、fuga()の中でAのインスタンスを 
生成させている
A#newメソッドをテストコード内で外側からフックしてしまって、
Aのインスタンスを自分で定義したモックにすげ替えているところです。
これにより、Aの実装に依存することなく(例では未実 
装にもかかわらず)、
また、テスタビリティを意識して実装コードを枉げることもなく、
Bの挙動のみに関しての本当の「単体」テストを記述することができ 
ます。

2個目のexampleは、stub!  の代わりに  
should_receive を使用した例です。
このケースにより、fuga() のロジック内で A#hoge を 
確実に呼び出している
ことを保証させることができます(1個目のexampleと微 
妙に内容が
かぶっていてあまりキレイな例でもないですが・・・)。

以上、ちょっとコードはいい加減ですが、雰囲気がだいたい伝わっ 
ていれば
幸いです。

--
松田 明 <ronnie@dio.jp>


In This Thread