tchikuba's blog

クリエイティブが輝ける組織をエンジニアリングする

Railsでテストを書く場合、FactoryGirlなDB接続するかmock_modelなモック作成か(Ebisu.rb#8)

前回のEbisu.rb#7に引き続き、 Ebisu.rb#8も参加しました。

勉強会の形式は前回同様で飲みながらRuby関連ネタを語り合う感じでした。 前回は19:30集合でしたが前回のKPTから20:00から開始でした。 今回は事前に仕込んだLTネタが3件あり話題が豊富でしたね。 当日の雰囲気はハッシュタグ#ebisurbの 4/25の参加者のつぶやき見てもらえればイメージ湧くかと。

後半ひと通りLT的な発表が終わってからお酒も進んでの雑談の中でRailsでのテストをどんな感じで書いてるか? という話題になりました。個人的に今回LTネタ的な感じで発表してみようかなと思っていて結局できなかったので 考えを整理する為にも書き残しておこうと思います。


結論から言うと私が関わるプロジェクトの場合はpoltergeist+turnip+Capybara+FactoryGirlで受入テストを、 Rspec+mockでユニットテストをそれぞれ書いています。 受入テストは正常系やKPIに直接関わるテストを中心に実装しています。 ユニットテストは基本カバレッジベースでモックを用いて疎結合なテストを実装しています。

前者の受入テストについては参加者の中での議論でpoltergeistやturnipを使うか否かで違いはあるものの それほど大きな違いはなさそうでした。翻ってユニットテストでFactoryGirlでDBに接続するテストを書くか、 モックを用いて疎結合にテストを書くかでは少なくとも参加者の中では二分していました。

個人的にはコンテキストによりけりでよりbetterな選択を繰り返していくことが大切だと思います。 なのでFactoryGirlでDB接続するテストを書くかモックでDB接続を極力せずテストを書くかは ケース・バイ・ケースでプロジェクト毎に合意を取りながら決めていけば良いのかなと。


という前提を踏まえながらも私がモックを使うテストを書く理由についてまとめておきます。

  • RailsはRestfulな設計思想が秀逸でその設計思想のレールに乗ると開発効率が上がる
  • Railsの設計思想を端的に表しているのがActiveRecord
  • 規模が小さいうちはthin-controller, thin-modelでスマートな開発が可能
  • ある程度のデータ量や複雑なビジネスロジックが追加されると段々これがfat-modelになりやすい
  • fat-modelをリファクタリングする方法としてこの記事が有名ですが、このようなリファクタリングや最初からクラス設計に組み込んで実装する場合、クラスやモジュールの依存関係が発生する
  • この依存関係を実装段階で出来るだけ分離しながら進めていく設計手法の助けとしてモックやスタブを駆使する

大体こんな感じです。


余談ですがこの辺り、Rails作者のDHHのブログエントリ 「TDD is dead. Long live testing.」 でTDDに一石を投じたエントリにも通じるような気がしています。 (和訳はこちら)

この話に言及し出すと長くなりそうなので別の機会に。次回のEbisu.rb#9のネタにでもしようかなw