FactoryGirlをCucumberから使うときに、step definitionを書く必要があるけれども、実はFactoryGirlに基本的な物が含まれているという話。でも英語だけなのが残念です。
基本手順
フィーチャにてレコードを1個追加
feature/mypost.feature
Senario: really simple feature for Post
Given the following post exists:
| Title | Body |
| a fun title | here is the content |
対応する Factory を書く
spec/factory_girl/mypost_factory.rb
FactoryGirl.define do
factory :post do
end
end
以上。
フィーチャを書くときの注意
- クラス名は小文字で
- アンダーバーではなくスペースにする
- 単数と複数に注意
example.feature
# AdminUserモデルで name 属性を "Mother" にする
Given a admin user exists with a name of "Mother"
# 2つの Post モデルを作る
And 2 posts exists
# 同じ Tag を 10 個作る
Given 10 tags exist with a name of "crazy"
# テーブルをもとに複数ユーザを追加
And the following users exist:
| Name | Email |
| hoge | hoge@me.com |
| fuga | |
フィーチャを書くときの小技
- インスタンスが少ないのであれば、1行でできる。
one_line
Given a user exists with a name of "norobust"
- 関連(association)
assoc
Given the following Author exists
| ID | Name |
| 12 | norobust |
And the following Posts exists
| Title | Author |
| Thanks God | Name: norobust |
- 関連(foreign key 指定してる場合)
ここでは、has_many :posts, :foreign_key => :watcher_id
みたいなのを前提に。
assoc
Given the following Author exists
| ID | Name |
| 12 | Carmit |
And the following Posts exists
| Title | watcher_id |
| Thanks God | ID: 14 |
もちろん Name: Carmit
でも大丈夫。
ファクトリーを書くときの注意
Given the following XXX exists
の XXX が factory の名前になるようにします。
feature
Given a guest user exists
factory
FactoryGirl.define do
factory :guest_user, :class => User do
end
end
おまけ
FactoryGirlに同梱のfeatureより。
feature
Scenario: the user, norobust, exists
When a user exists with name of "norobust"
Then I should find the following for the last user:
| Name |
| norobust |
要するに norobust ユーザを登録したら、最後のレコード(User.last)に norobust ユーザが居ますよというものです。
これをやるには、ステップを追加します。
step_definitions/database_steps.rb
Then /^I should find the following for the last (.*):$/ do |model, table|
model_class = model.gsub(" ","_").camelize.constantize
last_instance = model_class.last or raise "No #{model.pluralize} exist"
table.hashes.first.each do |key, value|
last_instance.attributes[key.underscore].to_s.should == value
end
end