ユニットテストにおけるフィクスチャとヘルパ。(mocha)
フィクスチャが欠点だらけ
- 書きにくい
- 分かりにくい(特にassociation)
- 遅い
そこで多くの人はモックとスタブを使いますが、モック/スタブにも次のような欠点があると思います。
製品コードの柔軟性が失われやすい。
つまり製品コードが使用するインターフェースをモック/スタブが決めてしまい、他の書き方をできなくなってしまうという現象です。
たとえばPeopleモデルのレコード数を数える場合、ただ数えるだけなら People.count
を使いますね。そこで People.count
をモックするわけですが、数えるだけでなく実際に全てのレコードを使うなら、 People.find(:all)
して得られたArrayの size
を使えばSQLの発行は1回で済みます。では People.find
もモックするのか?実際の製品コードではどちらでも書けるようにしておけば、リファクタリングのための自由度を残せます。つまりモック/スタブを使わず、DBにアクセスさせる方が開発しやすい場合があるということです。
ではどうするか
答えはテスト用データをセットアップするためのヘルパー群です。製品コードに自由度を残すためにDBは使いますがfixturesは使わないので、 セットアップの段階で必要なデータをDBに注入 してやる必要があります。しかし毎回 People.create :name => ...
とやっていたのではDRYでなくなってしまうので、ヘルパーを作るのです。例えば次のようなコードです。
class CommentObserverTest < Test::Unit::TestCase context 'With an issue, adding a comment' do setup do @issue, @client = an_issue_of_a_client emails.clear end should 'send a notification' do a_comment(@issue, an_account(@client), :private) assert_equal 1, emails.size end should 'not notify 3rd party members a private comment' do a_comment(@issue, an_account(a_client), :private) assert_equal 0, emails.size end end end