- とりあえず使ってみるべ。まずは FactoryGirl
FactoryGirlFactory.sequence :login do |i|
"login#{i}"
end
Factory.define(:user) do |user|
user.login {Factory.next(:login)}
user.name '(名称未設定)'
user.email {|u| "%s@example.com" % u.login}
user.password 'generic'
user.password_confirmation 'generic'
end |
- Syntaxが辛い。:user(クラス名), user(ブロック引数), user(receiver)の冗長性とか無理
- てか、Rubyがbundleで持っているべき
- 世の中はまだ1.8だし
- 構造が違うから直接1.8にバックポートするのは無理デスネ
- 1.8に適当なblankslate.rbをバックポート希望
- 閑話休題。この書式に耐えかねた先人(notahat)がMachinistを作成していますよ
- おし、それに乗っかろう
MachinistUser.blueprint do
login 'login'
name '(名称未設定)'
email {"%s@example.com" % login}
password 'generic' password_confirmation 'generic'
end |
- うがっ、すっきり!DSL 的で可読性が高い。これだよこれ!
- でも、FGにあったsequence機能はありませんが...
- そこはブロックだから、なんくるないさー。てか、「blueprint」てどういう意味?
- 文字通り「青写真」ですね。スケルトン(テンプレート)定義ぐらいの意味でよろしいかと
- Userのテンプレート定義で「User.blueprint」。簡潔だね。Machinist最高!!
- でもまぁ、blueprint書式ならFGにもありますけどね
- mjd!?
FactoryGirl + blueprint syntaxrequire "factory_girl/syntax/blueprint"
Factory.sequence :login do |i|
"login#{i}"
end
User.blueprint do
login {Factory.next(:login)}
name '(名称未設定)'
email {|u| "%s@example.com" % u.login}
password 'generic'
password_confirmation 'generic'
end |
- おいおいFactoryGirlって完璧じゃねーか
- さっそく :admin を追加しよう。FGで差分ってどう書くの?
FactoryGirl で継承Factory.define(:admin, :parent=>:user) do |u|
u.name '管理者'
end |
- って、ダサイ書き方に戻っちゃったよ。もしかして?
- はい。blueprint 書式だと継承は書けません。すいません
- ちょw。そもそも:parentなんてキーワードも来週にはもう忘れてるし
- 後発の Machinist ではどうなってるんでしょう?
Machinist で継承User.blueprint(:admin) do
name '管理者'
end |
- 素晴らしい!記述が直感的でエレガントだ
- Pete が必死に「FG は Syntax がダサイ!」とdisってた意味がわかったよ
- そう言えば、Syntax だけでなくて Philosophy も dis ってたよね?あれはどういう意味?
- あぁ、FGはinstanceをflatに管理してるんですよ
- どういうこと?
- 今、:admin を追加しましたよね。これが global に :admin として登録されちゃうんですよ
- なるほど、次に別クラスで:adminという名前を登録しようとしても競合するのか
- はい。仕方なく :user_admin, :role_admin みたいな名前空間を考慮して登録して行く事になります
- 確かに、:admin はないとしても、:dummy とかすぐぶつかりそう
FactoryGirlFactory.define(:user_dummy, :parent=>:user) do
...
end
Factory.define(:role_dummy, :parent=>:role) do
...
end
user = Factory(:user_dummy)
role = Factory(:role_dummy) |
- ダサイね。「Module 無き Ruby の世界」みたいな。考えただけで地獄ぽ
- そこで、Machinistではクラス毎に名前空間を持って管理してます
FactoryGirlUser.blueprint do
name '舞波'
end
User.blueprint(:dummy) do
name 'ダミーデータ'
end
Item.blueprint do
name '商品'
end
Item.blueprint(:dummy) do
name 'ダミー商品'
end
User.plan # => {'name' => '舞波'}
User.plan(:dummy) # => {'name' => 'ダミーデータ'}
Item.plan # => {'name' => '商品'}
Item.plan(:dummy) # => {'name' => 'ダミー商品'} |
- おいおいMachinsitって完璧じゃねーか
- てか、plan て何ですの?
- hashとして返すメソッドです。FGと同様に用途に応じて3種類のメソッドを用意しています
FactoryGirlとMachinistのメソッド比較| 戻り値 | FactoryGirl | Machinist |
|---|
| saved instance | Factory.create(:user) | User.make | | unsaved instance | Factory.build(:user) | User.make_unsaved | | Hash | Factory.attributes_for(:user) | User.plan |
- Machinistはシンプルで直感的だけど、クラスメソッドの汚染がやだな
- あぁ、あぅ、ふgぁ、それ言われたらヤバイな、って思ってたんですよ(ふがふが
- しかも一番使いそうな unsaved の名前が無駄に長い
- スイマセン。そこも4文字でいいのがあればよかったんですが
- いいよ。許す。この3つのメソッドは封印するよ。FGのよりも User.make の方が可読性高いし!
- 言い辛いんですが、FGにもそういう機能ありますけど...
- mjd!?
FactoryGirl + generaterequire 'factory_girl/syntax/generate'
# same as Factory.build(:user)
User.generate |
FactoryGirlのgenerate書式| メソッド | 内容 | ARで言うと | Factoryで言うと |
|---|
| generate | インスタンスを保存して返す | create | Factory.build (and save) | | generate! | generateして失敗時に例外を出す | create! | Factory.create | | spawn | インスタンスを作成して返す | new | Factory.build |
- 凄いけど名前混乱する。Factoryにそのまま委譲すればいいのに
(以下、鋭意妄想中)
|