今天就來繼續介紹 trait
、parent
、association
、alias
!
簡單來說就是更改 factory 名稱
# users.rb
FactoryBot.define do
factory :user, aliases: [:ck] do
association :profile
sequence(:name) { |n| "ck-#{n}"}
sequence(:email) { |n| "ck-#{n}@gmail.com" }
end
end
FactoryBot.build(:ck)
D, [2021-09-10T21:49:43.146980 #53028] DEBUG -- : (1.8ms) SELECT sqlite_version(*)
=> #<User id: nil, created_at: nil, updated_at: nil, name: "ck-1", email: "ck-1@gmail.com", phone: nil, shop_id: nil>
在 factory 裡再建立一筆 factory 可以指定 parent 繼承 parent 的 attributes
# profiles.rb
FactoryBot.define do
factory :profile do
address { "ck底加拉" }
age { 18 }
factory :ck_profile, parent: :profile do
age { 2 }
end
end
end
2.6.6 :001 > FactoryBot.build(:ck_profile)
D, [2021-09-10T21:52:58.330179 #53106] DEBUG -- : (1.7ms) SELECT sqlite_version(*)
=> #<Profile id: nil, address: "ck底加拉", age: 2, user_id: nil, created_at: nil, updated_at: nil>
可以在建立資料時關聯相關的 model 一起建立
# users.rb
FactoryBot.define do
factory :user do
association :profile
sequence(:name) { |n| "ck-#{n}"}
sequence(:email) { |n| "ck-#{n}@gmail.com" }
end
end
# profile.rb
FactoryBot.define do
factory :profile do
address { "ck底加拉" }
age { 18 }
end
end
2.6.6 :006 > user = FactoryBot.build(:user)
=> #<User id: nil, created_at: nil, updated_at: nil, name: "ck-4", email: "ck-4@gmail.com", phone: nil, shop_id: nil>
2.6.6 :007 > user.profile
=> #<Profile id: nil, address: "ck底加拉", age: 18, user_id: nil, created_at: nil, updated_at: nil>
也可以這樣寫
# users.rb
FactoryBot.define do
factory :user do
association :profile, factory: :ck_profile #找另一個profile的factory
sequence(:name) { |n| "ck-#{n}"}
sequence(:email) { |n| "ck-#{n}@gmail.com" }
end
end
# profiles.rb
FactoryBot.define do
factory :profile do
address { "ck底加拉" }
age { 18 }
factory :ck_profile do
address { "我家" }
age { 2 }
end
end
end
2.6.6 :001 > FactoryBot.build(:user).profile
D, [2021-09-10T21:37:18.376241 #52655] DEBUG -- : (1.6ms) SELECT sqlite_version(*)
=> #<Profile id: nil, address: "我家", age: 2, user_id: nil, created_at: nil, updated_at: nil>
也可以直接覆寫 attribute
# users.rb
FactoryBot.define do
factory :user do
association :profile, address: '庫拉比卡咖啡'
sequence(:name) { |n| "ck-#{n}"}
sequence(:email) { |n| "ck-#{n}@gmail.com" }
end
end
2.6.6 :001 > FactoryBot.build(:user).profile
D, [2021-09-10T21:42:43.492216 #52784] DEBUG -- : (1.7ms) SELECT sqlite_version(*)
=> #<Profile id: nil, address: "庫拉比卡咖啡", age: 18, user_id: nil, created_at: nil, updated_at: nil>
不過因為預設得資料最好不要一直關聯下去,會造成建立太多不必要的資料進而減慢測試速度所以建議使用等等介紹的 trait
!
類似於把資料都分隔開,需要用到時再引用
# users.rb
FactoryBot.define do
factory :user, aliases: [:ck] do
sequence(:name) { |n| "ck-#{n}"}
sequence(:email) { |n| "ck-#{n}@gmail.com" }
trait :ck_user do
association :profile
name 'ck'
email 'ck@ck.cc'
end
trait :normal_user do
name 'nono'
email 'nono@no.cc'
end
end
end
2.6.6 :002 > ck = FactoryBot.build(:user, :ck_user)
=> #<User id: nil, created_at: nil, updated_at: nil, name: "ck", email: "ck@ck.cc", phone: nil, shop_id: nil>
2.6.6 :003 > ck.profile
=> #<Profile id: nil, address: "ck底加拉", age: 18, user_id: nil, created_at: nil, updated_at: nil>
也可以一次用上多種 trait
# users.rb
FactoryBot.define do
factory :user, aliases: [:ck] do
sequence(:name) { |n| "ck-#{n}"}
sequence(:email) { |n| "ck-#{n}@gmail.com" }
trait :ck_name do
name { 'ck' }
end
trait :ck_email do
email { 'nono@no.cc' }
end
end
end
2.6.6 :001 > ck = FactoryBot.build(:user, :ck_name, :ck_email)
D, [2021-09-10T22:05:16.143022 #53864] DEBUG -- : (2.3ms) SELECT sqlite_version(*)
=> #<User id: nil, created_at: nil, updated_at: nil, name: "ck", email: "nono@no.cc", phone: nil, shop_id: nil>
當然他可以做很多組合技,我們之後範例會慢慢使用到,明天會再繼續介紹 factorybot !