factorygirl入門
DESCRIPTION
hamamatsu.rb #9 FactoryGirl入門(私が)の資料。 https://github.com/hamamatsu-rb/hamamatsu-rb.github.com/wiki 追加(2013/9/1): 最近は trait なんてのがあるようです。こちらがわかりやすかったです→ http://techracho.bpsinc.jp/morimorihoge/2013_08_23/12744TRANSCRIPT
FactoryGirl入門
hamamatsu.rb#9 2011/11/09
@suchi
なぜ Girlなの?
世界三大 ファクトリー
世界三大ファクトリー
• ファクトリーレコード
–マンチェスターのインディーズレーベル
• アンディ・ウォーホルのファクトリー
–ウォーホルのスタジオ
–当時の先鋭アーティストのたまり場
• うなぎパイファクトリー
–春華堂によるうなぎパイ工場
おそらく
イーディ Factory
Girl
サンプル(BBS)
https://github.com/suchi/fgbbs
Article
class Article < ActiveRecord::Base has_many :attaches has_many :comments validates_presence_of :title validates_presence_of :body validates_presence_of :user validates_uniqueness_of :title end
Attach
class Attach < ActiveRecord::Base belongs_to :article validates_presence_of :filename end
Comment
class Comment < ActiveRecord::Base belongs_to :article, :dependent => :destroy validates_presence_of :body validates_presence_of :user validates_presence_of :article_id end
Fixture(article.yaml)
one: title: タイトル body: こんにちは user: uchiyama two: title: また別のタイトル body: どうもどうも user: Cherencov
FactoryGirl
Factory.define :article |do| f f.title "タイトル" f.user "uchiyama" f.body "こんにちは" end
FactoryGirl
• Factory.create(:article)
– Articleインスタンスを返す
• Factory.create(:article, :title => "別のタイトル", :user => "mackato")
–属性をオーバーライドできる
• a = Factory.build(:article)
• a.changed? #=> true
– buildはDBに保存しない
エラー
>> Factory.create(:article) ActiveRecord::RecordInvalid: Validation failed: Title has already been taken from d:/usr/ruby-1.8/lib/...
Article
class Article < ActiveRecord::Base has_many :attaches has_many :comments validates_presence_of :title validates_presence_of :body validates_presence_of :user validates_uniqueness_of :title end
Sequenceを使う
Factory.sequence(:article) do |n| "article_#{n}" end Factory.next(:article) #=> "article_1" Factory.next(:article) #=> "article_2"
Sequence
[:article_title, :user_name, :body].each do |sym| Factory.sequence(sym) do |n| "#{sym.to_s}_#{n}" end end Factory.next(:article_title) #=> "article_1" Factory.next(:article_title) #=> "article_2" Factory.next(:article_title) #=> "article_3"
Article.titleにシーケンスを使う
Factory.define :article |do| f f.title Factory.next(:article_title) f.user "uchiyama" f.body "こんにちは" end
エラー
Factory.define :article |do| f f.title Factory.next(:article_title) f.user "uchiyama" f.body "こんにちは" end Factory.create(:article) #=> ActiveRecord::RecordInvalid: Validation failed: Title has already been taken
遅延評価
Factory.define :article |do| f f.title { Factory.next(:article_title)} f.user "uchiyama" f.body "こんにちは" end
関連
• シンボルと作成するクラスが異なる場合は:classオプションで指定
Factory.define :article_with_attaches, :class => Article do |f| f.title { Factory.next(:article_title) } f.user 'uchiyama' f.body '"こんにちは' f.attaches [ Factory(:attach), Factory(:attach) ] end
添付ファイル付Article
• →ロード時にエラー
Factory.define :article_with_comment, :class => Article do |f| f.title { Factory.next(:article_title) } f.user 'uchiyama' f.body '"こんにちは' f.comments [ Factory(:comment), Factory(:comment) ] end
コメント付Article
• →インスタンス作成時にエラー
Factory.define :article_with_comment, :class => Article do |f| f.title { Factory.next(:article_title) } f.user 'uchiyama' f.body '"こんにちは' f.comments {[ Factory(:comment), Factory(:comment) ]} end
遅延評価にしてみる
Comment
class Comment < ActiveRecord::Base belongs_to :article, :dependent => :destroy validates_presence_of :body validates_presence_of :user validates_presence_of :article_id end
after_createを使う
Factory.define :article_with_comments, :class => Article do |f| f.title { Factory.next(:article_title) } f.user { Factory.next(:user_name) } f.body 'こんにちは' f.after_create do |article| comments = [ Factory(:comment, :article_id => article.id), Factory(:comment, :article_id => article.id) ] end end
• after_create - Article.createが呼ばれたあと、インスタンスを引数に呼ばれる
その他便利な機能
• Factory.attributes_for(:article)
–属性のhashを返す
– [:title=>"article_title_6", :user=>"uchiyama", :body=>"こんにちは"}
• Factory.stub(:article)
– stubを作成する
欠点 欠点
• Factory名称の名前空間がグローバル
• 記法がちょっとダサい
• 後発のFablicationはもっと洗練されているらしい
• Factory名称の名前空間がグローバル
• 記法がちょっとダサい
• 後発のFablicationはもっと洗練されているらしい
• 実験はコンソールで --sandboxオプションをつけて
> ruby script/console --sandbox
TIPS
Q&A Q&A