Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Factory Girl

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Factory Girl

How to use Factory Girl for creating model fakes in your test. Video where I talk over it the whole time: https://vimeo.com/119875543

Avatar for Ben Kreeger

Ben Kreeger

February 13, 2015
Tweet

More Decks by Ben Kreeger

Other Decks in Programming

Transcript

  1. Summing up a complex human being in two hours is

    like an MTV spot about Nelson Mandela cut to a Kanye West track. 1 Brian Holcomb, CinemaBlend.com 2
  2. Integrate it $ mkdir -p ./spec/support $ vim ./spec/support/factory_girl.rb #

    spec/support/factory_girl.rb RSpec.configure do |config| config.include FactoryGirl::Syntax::Methods end 5
  3. Define them $ mkdir -p ./spec/factories $ vim ./spec/factories/user_factories.rb #

    spec/factories/user_factories.rb FactoryGirl.define do factory :user do first_name "Jon" last_name "Snow" is_nights_watch true end end 6
  4. Refine them FactoryGirl.define do factory :user do first_name "Jon" last_name

    "Snow" is_nights_watch true trait(:knows_nothing) do knows [] end end end 7
  5. Relate them FactoryGirl.define do factory :animal do species "Sciurus carolinensis"

    name "squirrel" end factory :direwolf, class: Animal do species "Canis dirus" name "direwolf" end end 8
  6. Relate them FactoryGirl.define do factory :user do first_name "Jon" last_name

    "Snow" is_nights_watch true trait(:knows_nothing) { knows [] } trait(:has_animal) { animal } trait(:has_direwolf) do association :animal, factory: :direwolf end end end 9
  7. Make them saved_instance = FactoryGirl.create(:user) # <User id: 1, first_name:

    "Jon", last_name: "Snow"> non_persisted = FactoryGirl.build(:user) # <User id: nil, first_name: "Jon", last_name: "Snow"> hash = FactoryGirl.attributes_for(:user) # { first_name: "Jon", last_name: "Snow" } If you're using Rspec and have included the FactoryGirl helpers… saved_instance = create(:user) # <User id: 1, first_name: "Jon", last_name: "Snow"> 10
  8. Make them user = create(:user, :knows_nothing, :has_direwolf) # <User id:

    1, first_name: "Jon", last_name: "Snow", knows: []> user.animal # <Animal id: 1, species: "Canis dirus", name: "direwolf"> 11
  9. Make them master_at_arms = create(:user, :has_animal, first_name: "Alliser", last_name: "Thorne")

    # <User id: 1, first_name: "Alliser", last_name: "Thorne"> master_at_arms.animal # <Animal id: 1, species: "Sciurus carolinensis", name: "squirrel"> 12
  10. Child factories with traits factory :user do on_nights_watch false #

    Traits can be cascaded/layered. Last one gets precedence. trait(:nights_watch) { on_nights_watch(true) } trait(:has_direwolf) { direwolf } factory :jon_snow, traits: %i(nights_watch has_direwolf) end # To use... create(:jon_snow) # <User id: 1, name: "Jon Snow", on_nights_watch: true> 15
  11. Lazily-computed attributes factory :user do # Use when your data

    is not static. signed_up_at { 21.seconds.ago } end 16
  12. Sequences factory :user do # To ensure your data is

    unique-ish. sequence(:codename) { |idx| "user-#{idx}" } end 17
  13. Fake things with Faker factory :user do first_name { Faker::Name.first_name

    } email { Faker::Internet.email } bitcoin { Faker::Bitcoin.address } about { Faker::Lorem.paragraph(2).join("\n") } end Make your tests less dependent on specific data. This is a Good Thing™. 18
  14. Dependent attributes factory :user do first_name "Jon" last_name "Snow" #

    This is super simple, but must be lazily-evaluated ygritte_says { "You know nothing, #{first_name} #{last_name}."} end 19
  15. Non-persisted (transient) attributes factory :user do ignored do broke_vows false

    end name "Jon Snow" after_create do |user, factory_instance| if factory_instance.broke_vows user.revoke_nights_watch_status! end end end 20
  16. Batch creation animals = FactoryGirl.create_list(:animal, 25) unsaved_direwolves = FactoryGirl.build_list(:direwolf, 5)

    lannisters = FactoryGirl.create_list(:user, last_name: "Lannister", sigil: "Lion") 22