以前から試してみたかったfactory girl。
こないだ試した twitter-auth at master のテストで使われていたので、これを機にinstallしてみた。
(他にもfakewebやらremarkable_railsなど、いろいろ気になるのが使われてる。)
名前もなんかいいよね。girlって付くと。
thoughtbot's factory_girl at master - GitHub
参考
has_many throughでの例が非常に分かりやくて参考になります。
has_manyなフィクスチャを書くのに疲れたらFactory Girlがオススメ! - func09
バージョン
readmeよく見たらいろいろバージョンがあるらしい。
現時点では下記のよう。
(あと、いろいろforkされててfactory_boyっつーのもあるらしい。気になる)
factorygirl2(beta version)
factorygirl1.3.x(stable version for Rails3.0)
factorygirl1.2.4(for Rails2.x)
thoughtbot's factory_girl at v1.2.4 - GitHub
(なんか1.2.5もあるみたいだが、、、github上でversionの差分確認ってできんのだろうか?)
今回は
とりあえずRails2.3系のプロジェクトで使いたいというのもあるので
1.2.4を試す。感触よければ、あとで1.3.xも試す。
install
$ gem install factory_girl -v=1.2.4 --no-ri --no-rdoc
設定
config.gem "factory_girl", :version => '1.2.4', :source => "http://gemcutter.com"
readmeには、enviroment.rbって書いてるけど、config/environments/test.rbの方がいいかも。
書き方
下記ファイルにfactory情報(テストデータ)を書くとtest時に使えるようになります。
まぁ、モデル毎に定義したい場合は、factories/*.rb って感じですよ。
test/factories.rb spec/factories.rb test/factories/*.rb spec/factories/*.rb
基本
# adminって名前でUser classのデータ定義をします Factory.define :admin, :class => User do |u| u.first_name 'Admin' u.last_name 'User' u.admin true end # class名を文字列で指定してもok # Factory.define :admin, :class => 'user' do |u| # # また、userって名前にすると(class名と一緒だと)classオプションは省略できます # Factory.define :user do |u|
関連を書くのが便利
これ肝だと思うんだけど、readmeに詳細が無い。
User:Blog 1対多の関係(has_many)だとすると
UserにBlogを複数持っているという関連がFactoryにすんなり書ける。
(Fixtureより随分分かりやすい)
#User Factory.define :hoge, :class => User do |u| u.first_name 'hoge' u.last_name 'fuga' u.admin true u.blogs{[Factory(:first),Factory(:latest)]} end #Blog Factory.define :first, :class => Blog do |b| b.title 'hogehoge' b.description 'fugafuga' end Factory.define :latest, :class => Blog do |b| b.title 'mogumogu' b.description 'munyamunya' end
readmeには下記のような書き方が紹介されている。
Factory.define :post do |p| # ... p.author {|author| author.association(:user, :last_name => 'Writely') } end
主な使い方
# Returns a User instance that's not saved # save前。user.save などが可能。user.new_record? # => true となる user = Factory.build(:user) # Returns a saved User instance # save後。 user = Factory.create(:user) # Same as Factory.create :user: # shortcut # 基本はコレかな。 # default_strategyオプションで、shortcutの動作を変えれるみたいだが、あんまり使わなさそう user = Factory(:user) # Returns a hash of attributes that can be used to build a User instance: # hashが返ります。 #{:name=>"bob", # :pages=> # [#<Page id: 1, title: "Google", url: "http://www.google.com/", bookmark_id: nil, created_at: "2010-10-20 16:35:20", updated_at: "2010-10-20 16:35:20">, # <Page id: 2, title: "Yahoo!", url: "http://www.yahoo.com/", bookmark_id: nil, created_at: "2010-10-20 16:35:20", updated_at: "2010-10-20 16:35:20">]} attrs = Factory.attributes_for(:user) # Returns an object with all defined attributes stubbed out: # ぱっと見よく分からなかったが、実行してみると # idを仮で返してくれる。(つまりstub。まんまだけど) # <User id: 1001, name: "bob", bookmark_id: nil, created_at: nil, updated_at: nil> stub = Factory.stub(:user)
sequence
は便利かな。nextで連番が使用可能。
# Defines a new sequence Factory.sequence :email do |n| "person#{n}@example.com" end Factory.next :email # => "person1@example.com" Factory.next :email # => "person2@example.com"
あとは
Callbacks(after_build, after_crate, after_stub)やら
Alternate Syntaxesっつー機能もあるようだ。
まだよく分かってない。
とりあえず、もりもりテスト書いていこう。
おまけ
fixtureの代わりとしては、とりあえずダントツのようです。
The Ruby Toolbox Search