ユニットテストにおけるフィクスチャとヘルパ。(mocha)

d.hatena.ne.jp

フィクスチャが欠点だらけ

  • 書きにくい
  • 分かりにくい(特に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
その他参考

qiita.com