15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FactoryGirlアンチパターン(?)

Posted at

FactoryGirlの使い方はググればすぐ出て来るんだけど、「適切」な使い方、いわゆるベストプラクティスを紹介、あるいは模索しているページは日本語ではほとんどない(英語だとちょくちょくある、たとえば「FactoryGirl slow」でググってみると良いと思う)。テストの改善を任されたのでせっかくだからその記録をここに残しておくことでFactoryGirlのより良い書き方の議論が盛り上がるようなことになればうれしいな、と思う。

アンチパターン1:とにかくcreate

SQLアンチパターンみたくかっこいい二つ名をつけたかった気もするけど後で超絶恥ずかしくなるのはわかってるので、そのままの名付けをしていく。
とにかくすべてcreatecreate_listを使うというパターン。本当に実際の環境をエミュレートしていることに間違いはないのだけど、とにかく遅い。IOを両方行っているし、単一のobjectならいざ知らず、巨大関連からなる一つの「系統樹」とでもいうべき一連のobjectを一つのexampleのたびにDBIOするのはどう考えても無駄なコストだ。特にただ単にメソッドの振る舞いをテストするようなときはbuildbuild_stubbedで十分だと思われる。むしろデフォルトをbuildbuild_stubbedにして問題が発生したときに初めてcreateを使うことを考慮する、くらいでいいかもしれない。
参考:https://robots.thoughtbot.com/speed-up-tests-by-selectively-avoiding-factory-girl
https://robots.thoughtbot.com/use-factory-girls-build-stubbed-for-a-faster-test)

アンチパターン2:異常に根深いassociationと遠隔操作のごときtrait

上にも少し話題にあげたけど、あまりassociationを深くしすぎると融通が利かなくなるので、二段階異常のassociationについてはstubメソッドで対応する、みたいにしたほうがいい気がする。そして、これをtraitで管理するとどういう風になるのかというと、

.rb
Model One
 belongs_to Two
 belongs_to Three

Model Two
#a/bの二種類を取りうる

Model Three
#c/dの二種類を取りうる

Model Four
belongs_to Two
#e/fの二種類を取りうる

みたいな関連になってるときに、
with_Two_is_a_and_Four_is_e_and~みたいな直接ではない関連を制御するためのtraitが出てきだす。そうなると辛くて、すべてのパターンを網羅するようにfactoryを定義していく義務みたいなのが生じてくる。しかし、一段階より大きい深さの関連についてはstubでごまかす、みたいな風にしとくと、factory自体はそこまで複雑にならずに済む。factoryの定義とテストが密結合だと、今までは同じfactoryで済んでたケースが仕様が変わってあるケースだけ先のほうの関連objectの何かしらの設定を変更しないといけない、となったときに、trait職人みたいになってくるのはつらい。やはりfactoryは直接関連しているobjectにのみ責任を持つべきだと思う。(デメテルの法則)

TODO:これについて書く(ちゃんと読む)。

ご意見や新たなアンチパターン、ベストプラクティスをお待ちしております。この記事は加筆修正していく予定です。

15
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?