Rails ã¢ã³ããã¿ã¼ã³ - éã³ã¤ãããã¡ã¯ããªã¼ (factory_girl)
æè¡æ¸å ¸ã¯æ¸ãå´ã§åå ãããæ°æã¡ã¯ãããã©ãæ¸ããã¿ã¨æ¸ãæéããããã©ããâ¦
— ç¥é@ãªãªã«ã«ã¨ã³ã¸ã㢠(@sinsoku_listy) 2017å¹´4æ9æ¥
ãã¼ãèªåã®ç¥ã£ã¦ãRailsã¢ã³ããã¿ã¼ã³ã¨ãæ¸ããããããèªåã®ç¯ãã罪(ã¢ã³ããã¿ã¼ã³)ãè´ç½ªãããâ¦ã
— ç¥é@ãªãªã«ã«ã¨ã³ã¸ã㢠(@sinsoku_listy) 2017å¹´4æ9æ¥
æè¡æ¸å
¸2 ã«è¡ã£ããç¡æ§ã«æ¬ãæ¸ããããªã£ããã©ãæ¬æ¸ãã®ã¯ é¢å 大å¤ã§ãã
ã¨ããããã§ãã¨ããããããã°ã«è¨äºã1ã¤æ¸ãã¦ã¿ãã
factory_girl
factory_girl ã¯ãã¹ãç¨ãã¼ã¿ãä½æããã¨ãã«ä½¿ã gem ã§ãã
ä¸è¨ã¯ User ã®ã¢ãã«ãå®ç¾©ãããã¡ã¯ããªã¼ã§ãã
FactoryGirl.define do factory :user do first_name "John" last_name "Doe" admin false end end
ãã®ãã¡ã¯ããªã¼ãã User ã®ãã¹ããã¼ã¿ãçæãããã¨ãã§ãã¾ãã
FactoryGirl.create(:user) #=> #<User id: 1, first_name: "John", ...
factory_girl
ã¯é¢é£å
ã®ã¬ã³ã¼ããèªåçæããããé£çªãçæããããçµæ§å¤æ©è½ã ã£ãããã¾ãã
ãã®ãããã®è©³ç´°ãç¥ãããæ¹ã¯å ¬å¼ã® README ãèªãããè±èªãè¦æãªãæ¥æ¬èªã®ç´¹ä»è¨äºãªã©ãèªãã¨è¯ãã§ãã
éã³ã¤ãããã¡ã¯ããªã¼
ãããããæ¬é¡ã§ãfactory_girl
ã§å®ç¾©ãããã¡ã¯ããªã¼ã¯æéãçµã£ãããä½æè
ãæªçã 㨠éã³ã (ï¼ãã«ããã¥ãããã§ããªããªãï¼ãã¨ãããã¾ãã
éã³ã¤ãããã¡ã¯ããªã¼ä¾ãç´¹ä»ãã¦ã¿ããã¨æãã¾ãã
2å以ä¸ãã«ãã§ããªã
class User validates :nickname, uniqueness: true end FactoryGirl.define do factory :user do nickname "sinsoku" end end
ããã¯ã²ã©ãã uniqueness å¶ç´ã«ãã2åç®ã®ãã«ãã¯å¤±æãã¾ãã
FactoryGirl.define do factory :user do sequence(:nickname) { |n| "nickname_#{n}" } end end
ä¸è¨ã®ããã« sequence ã使ã£ã¦åé¿ãã¹ãã§ãã
build_stubbed ãªã®ã«ã¬ã³ã¼ããçæããã
ã¯ã©ã¹ã®å±æ§ã ãã§ãã¹ããã§ããï¼ DB ã¢ã¯ã»ã¹ãä¸è¦ãªï¼ã±ã¼ã¹ãããã¾ãã
class Book def published? published_at <= Time.current end end
ãã®ãããªã¡ã½ããã®ãã¹ãã§ã¯ DB ã¢ã¯ã»ã¹ãããªãããã« build_stubbed
ã使ãã¹ãã§ãã*1
ãããããã¡ã¯ããªã¼ãä¸è¨ã®ãããªå®ç¾©ã ã¨ã¬ã³ã¼ããçæããã¦ãã¾ãã¾ãã
FactoryGirl.define do factory :book do author { create(:user) } published_at '2017-04-10' end end
ãã㯠association ã使ã£ã¦å®ç¾©ãã¹ãã§ãã
FactoryGirl.define do factory :book do association :author, factory: :user published_at '2017-04-10' end end
association ã使ããã¨ã§ã build_stubbed
ã®æã«ã¬ã³ã¼ããçæãããªããªãã¾ãã
ããã©ã«ãã®ãã¡ã¯ããªã¼ãéã
FactoryGirl.define do factory :user do name 'serval' transient do friends_count 10 end after(:create) do |_user, evaluator| create_list(:user, evaluator.friends_count) end end end
ããã©ã«ãå¤ã®ãã¬ã³ãºãå¤ããã¾ãï¼ï¼
FactoryGirl.define do factory :user do name 'serval' factory :user_with_friends do transient do friends_count 10 end after(:create) do |_user, evaluator| create_list(:user, evaluator.friends_count) end end end end
ããã©ã«ãã®ãã¡ã¯ããªã¼ã¯ã·ã³ãã«ã«ä¿ã¡ããã¬ã³ãºã®å¤ããã¡ã¯ããªã¼ã¯å¥ã«ãã¦ããã¾ãããã
æ¡ä»¶ã®å¿ è¦ãªãã¡ã¯ããªã¼
class Servant belongs_to :master validate :must_be_valid_master TEAM = { 'Artoria Pendragon' => 'Shirou Emiya' } private def must_be_valid_master errors.add(:master, ' is invalid') unless TEAM[name] == master.name end end FactoryGirl.define do factory :servant do association :master, factory: :user name 'Artoria Pendragon' end end
ãã®ãã¡ã¯ããªã¼ã¯ master ã ‘Shirou Emiya’ ã®ã¨ãã ããã«ãã§ãã¾ãã
user = FactoryGirl.create(:user, name: 'Shirou Emiya') servant = FactoryGirl.create(:servant, master: user)
ãã®ããã«ããã«ãæã«å¿ è¦ãªé¢é£ã渡ããããªãã¡ã¯ããªã¼ã¯ä½¿ãã¥ããã§ãã
FactoryGirl.define do factory :servant do association :master, factory: :user, name: 'Shirou Emiya' name 'Artoria Pendragon' end end
FactoryGirl.create(:servant)
ã ãã§ãã«ããåºæ¥ãããã«ãã¦ããã¹ãã§ãã
ãã®ä»
æéã®çµéã«ããããªãã¼ã·ã§ã³ã追å ã»å¤æ´ãããããã¢ãã«ã®é¢é£ãå¤ãã£ã¦ãã¾ãããã¡ã¯ããªã¼ãéã³ã¦ãã¾ããã¨ãããã¾ãã
ã¢ã³ããã¿ã¼ã³ã¸ã®å¯¾ç
幸ã factory_girl
ã«ã¯ Lint ãã¤ãã¦ãã¾ãã
# lib/tasks/factory_girl.rake namespace :factory_girl do desc "Verify that all FactoryGirl factories are valid" task lint: :environment do if Rails.env.test? begin DatabaseCleaner.start FactoryGirl.lint ensure DatabaseCleaner.clean end else system("bundle exec rake factory_girl:lint RAILS_ENV='test'") end end end
ä¸è¨ã®ãã㪠rake ã¿ã¹ã¯ãä½æãã CI ã§å¸¸ã«ãã¡ã¯ããªã¼ããã«ãã§ããããã§ãã¯ãã¦ããã®ãè¯ãã§ãããã
ããã
ããã¨æãåºãã factory_girl
ã«é¢ããã¢ã³ããã¿ã¼ã³ãæ¸ãã¦ã¿ã¾ããã
ä»ã®ã¢ã³ããã¿ã¼ã³ã¯ããæ°ã¨æéãããã°æ¸ã…ããï¼
*1:ç¡é§ãªã¬ã³ã¼ããçæããã¨ãã¹ããé ããªã£ã¦ãã¾ãã¾ãã