為什么要用factory_girl
在寫測試的時候,經(jīng)常需要構(gòu)造數(shù)據(jù)。
而對于我們所要構(gòu)造的數(shù)據(jù):
- 除特殊原因,我們需要構(gòu)建合法的數(shù)據(jù)
- 對于絕大多數(shù)測試數(shù)據(jù),我們只在乎部分字段(和被測試內(nèi)容相關(guān)的),換句話說,剩下的字段可以是默認(rèn)的。
而factory girl剛好為解決這些問題提供了一個方便的機制。
factory_girl的使用
-
原則
factory的wiki解釋是: factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
既一個用來創(chuàng)建對象的地方,而這個地方并不需要我們關(guān)注細(xì)節(jié)。在寫測試的時候,我們應(yīng)該盡可能把數(shù)據(jù)創(chuàng)建,放到factory_girl里面。
這樣做的好處是:
一,重用。
二,提供了抽象,讓我們更加關(guān)注所要進(jìn)行測試的那一部分,而不是如何構(gòu)造數(shù)據(jù)。
三,便于維護(hù)。開發(fā)中,數(shù)據(jù)結(jié)構(gòu)往往是變化的。我們把數(shù)據(jù)創(chuàng)建放在了一個部分,如果數(shù)據(jù)結(jié)構(gòu)變化了,需要進(jìn)行更改,只要改一個地方就好了。 -
創(chuàng)建對象
# 創(chuàng)建對象
FactoryGirl.define do
factory :user do
name "Mike"
email "user@example.com"
end
end
FactoryGirl.create(:user, name: "New Name")
# => #<AdminUser: name: "New Name", email: "email "user@example.com")# 唯一字段 factory :user do sequence(:email) { |n| "user-#{n}@example.com" } end # 每次產(chǎn)生不一樣的字段,假設(shè)我們使用了Faker這個gem factory :user do sequence(:name) { Faker::Name::name } end # 一次創(chuàng)建多個對象 FactoryGirl.create_list(:user, 2) # 創(chuàng)建兩個user -
創(chuàng)建帶關(guān)聯(lián)的對象
# 關(guān)聯(lián) FactoryGirl.define do factory :user do email "user@example.com" end factory :post do user end end # 相當(dāng)于 user = User.new user.email = "user@example.com" user.save! post = Post.new post.user = user post.save! # 多態(tài) FactoryGirl.define do factory :post do association :author, factory: :user end end # 一對多 FactoryGirl.define do factory :post do name "post-name" factory :post_with_comments do after(:create) do |post, evaluator| create_list(:comment, 5, post: post) end end end end # 設(shè)置一對多的數(shù)量 FactoryGirl.define do factory :post do name "post-name" factory :post_with_comments do transient do comments_count 5 end after(:create) do |post, evaluator| create_list(:comment, evaluator.comments_count, post: post) end end end end create(:post_with_comments, 2) # 有五個comments的post create(:post_with_comments, 2) # 有兩個comments的post