factory girl

104
Factory Girl A Brief Introduction Using Ruby on Rails

Upload: gabe-evans

Post on 05-Dec-2014

7.209 views

Category:

Documents


1 download

DESCRIPTION

A not so brief overview of Factory Girl's features and basic usage.

TRANSCRIPT

Page 1: Factory Girl

Factory GirlA Brief Introduction Using Ruby on Rails

Page 2: Factory Girl

Factory GirlA Brief Introduction Using Ruby on Rails

Yet Another Blog Example

Page 3: Factory Girl

What’s Factory Girl?

Page 4: Factory Girl

A Replacement for Fixtures

Page 5: Factory Girl

Provides a Simple DSL

Page 6: Factory Girl

Keeps TestsFocused & Readable

Page 7: Factory Girl

Builds Objects Instead of Database Records

Page 8: Factory Girl

Installation

Page 9: Factory Girl

Gemfile

Page 10: Factory Girl

group :development, :test do gem ‘factory_girl_rails’end

Gemfile

Page 11: Factory Girl

$ bundle install

Page 12: Factory Girl

Defining a Factory

Page 13: Factory Girl

spec/factories/

Page 14: Factory Girl

spec/factories/users.rb

Page 15: Factory Girl

spec/factories/posts.rb

Page 16: Factory Girl

spec/factories/comments.rb

Page 17: Factory Girl

spec/factories/products.rb

Page 18: Factory Girl

spec/factories/users.rb

Page 19: Factory Girl

FactoryGirl.define do factory :user do name ‘Joe Blow’ email ‘[email protected]’ password ‘p@ssw0rd’ admin false endend

spec/factories/users.rb

Page 20: Factory Girl

spec/models/user_spec.rb

Page 21: Factory Girl

spec/models/user_spec.rb

describe User do

end

Page 22: Factory Girl

spec/models/user_spec.rb

describe User do subject { FactoryGirl.create(:user) }

end

Page 23: Factory Girl

spec/models/user_spec.rb

describe User do subject { FactoryGirl.create(:user) }

its(:name) { should == ‘Joe Blow’ }

end

Page 24: Factory Girl

spec/models/user_spec.rb

describe User do subject { FactoryGirl.create(:user) }

its(:name) { should == ‘Joe Blow’ } its(:email) { should == ‘[email protected]’ }

end

Page 25: Factory Girl

describe User do subject { FactoryGirl.create(:user) }

its(:name) { should == ‘Joe Blow’ } its(:email) { should == ‘[email protected]’ }

it { should_not be_admin }end

spec/models/user_spec.rb

Page 26: Factory Girl

FactoryGirl.create(:user)

Page 27: Factory Girl

FactoryGirl.build(:user)

Page 28: Factory Girl

FactoryGirl.build_stubbed(:user)

Page 29: Factory Girl

spec/spec_helper.rb

Page 30: Factory Girl

RSpec.configure do |config| config.include FactoryGirl::Syntax::Methodsend

spec/spec_helper.rb

Page 31: Factory Girl

FactoryGirl.create(:user)

Page 32: Factory Girl

create(:user)

Page 33: Factory Girl

build(:user)

Page 34: Factory Girl

build_stubbed(:user)

Page 35: Factory Girl

spec/models/user_spec.rb

describe User do subject { create(:user) }

its(:name) { should == ‘Joe Blow’ } its(:email) { should == ‘[email protected]’ }

it { should_not be_admin }end

Page 36: Factory Girl

Overriding Attributes

Page 37: Factory Girl

Keep Only Relevant Attributes in Tests

Page 38: Factory Girl

spec/models/user_spec.rb

context ‘a duplicate email address’ do it { should_not be_valid }end

Page 39: Factory Girl

context ‘a duplicate email address’ do let(:first_user) { User.create(name: ‘Joe First’, email: ‘[email protected]’, password: ‘test123’, admin: false) } subject { User.new(name: ‘Joe Duplicate’, email: first_user.email, password: ‘test123’, admin: false) }

it { should_not be_valid }end

spec/models/user_spec.rb

Page 40: Factory Girl

context ‘a duplicate email address’ do let(:user) { create(:user) } subject { build(:user, email: user.email) }

it { should_not be_valid }end

spec/models/user_spec.rb

Page 41: Factory Girl

Lazy Attributes

Page 42: Factory Girl

Lazy Attributes Are Dynamic Attributes

Page 43: Factory Girl

spec/factories/posts.rb

FactoryGirl.define do factory :post do title ‘This is my post.’ content ‘There are many like it, but this one is mine.’ published_at Time.now endend

Page 44: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)

Page 45: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 1, title: “This is my post.”, content: “There are many like it, but this one is mine.”, published_at: 2012-12-20 23:47:34 UTC>

Page 46: Factory Girl

group :development, :test do gem ‘factory_girl_rails’ gem ‘ffaker’end

Gemfile

Page 47: Factory Girl

spec/factories/posts.rb

FactoryGirl.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } endend

Page 48: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)

Page 49: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 2, title: “Lorem ipsum dolor sit amet, consectetur adipiscing elit.”, content: “Pellentesque adipiscing varius suscipit …”, published_at: 2012-12-20 23:48:14 UTC>

Page 50: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 3, title: “Nulla id augue ut mauris pharetra tincidunt ac sed velit.”, content: “Nullam tincidunt, dolor quis pellentesque …”, published_at: 2012-12-20 23:49:06 UTC>

Page 51: Factory Girl

Sequences

Page 52: Factory Girl

Reuse Common Attributes

Page 53: Factory Girl

FactoryGirl.define do sequence :email do |n| “person#{n}@example.com” endend

spec/factories/sequences.rb

Page 54: Factory Girl

FactoryGirl.define do factory :user do name { Faker::Name.name } email password ‘p@ssw0rd’ admin false endend

spec/factories/users.rb

Page 59: Factory Girl

Dependent Attributes

Page 60: Factory Girl

Attributes FromOther Attributes

Page 61: Factory Girl

spec/factories/users.rb

FactoryGirl.define do factory :user do name ‘Joe Blow’ email ‘[email protected]’ password ‘p@ssw0rd’ admin false endend

Page 62: Factory Girl

spec/factories/users.rb

FactoryGirl.define do factory :user do name ‘Joe Blow’ email { ‘#{name.gsub(/\s/, ‘.’)}@example.com’.downcase } password ‘p@ssw0rd’ admin false endend

Page 63: Factory Girl

irb(main):001:0> FactoryGirl.create(:user)=> #<User id: 1, name: “Joe Blow”, email: “[email protected]”, password: “p@ssw0rd”, admin: false>

Page 64: Factory Girl

irb(main):001:0> FactoryGirl.create(:user, name: ‘Joe Mama’)=> #<User id: 2, name: “Joe Mama”, email: “[email protected]”, password: “p@ssw0rd”, admin: false>

Page 65: Factory Girl

Traits

Page 66: Factory Girl

Specify Types Of Factories

Page 67: Factory Girl

describe Post do context ‘an unpublished post’ do subject { create(:post, published_at: nil) }

it ‘will never be read’ do # ... end endend

Page 68: Factory Girl

FactoryGirl.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } endend

spec/factories/posts.rb

Page 69: Factory Girl

FactoryGirl.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } trait :unpublished do published_at nil end endend

spec/factories/posts.rb

Page 70: Factory Girl

describe Post do context ‘an unpublished post’ do subject { create(:post, :unpublished) }

it ‘will never be read’ do # ... end endend

spec/models/post_spec.rb

Page 71: Factory Girl

Associations

Page 72: Factory Girl

Build Associated Objects From Factories

Page 73: Factory Girl

class Post < ActiveRecord::Base belongs_to :userend

app/models/post.rb

Page 74: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: …, title: “…”, content: “…”, published_at: …, user: nil>

Page 75: Factory Girl

FactoryGirl.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } trait :unpublished do published_at nil end endend

spec/factories/posts.rb

Page 76: Factory Girl

FactoryGirl.define do factory :post do user title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } trait :unpublished do published_at nil end endend

spec/factories/posts.rb

Page 77: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)=> #<Post …, user: #<User id: 123, name: “John Wayne”, …>>

Page 78: Factory Girl

Transient Attributes

Page 79: Factory Girl

Customize Behavior With Fake Attributes

Page 80: Factory Girl

FactoryGirl.define do factory :post do ignore do unapproved false end

title { unapproved ? “ಠ_ಠ” : “This is my post.” } endend

spec/factories/posts.rb

Page 81: Factory Girl

FactoryGirl.define do factory :post do ignore do unapproved false end

title { unapproved ? “ಠ_ಠ” : “This is my post.” } endend

spec/factories/posts.rb

Page 82: Factory Girl

FactoryGirl.define do factory :post do ignore do unapproved false end

title { unapproved ? “ಠ_ಠ” : “This is my post.” } endend

spec/factories/posts.rb

Page 83: Factory Girl

irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 2, title: “This is my post.”>

Page 84: Factory Girl

irb(main):001:0> FactoryGirl.create(:post, unapproved: true)=> #<Post id: 2, title: “ಠ_ಠ”>

Page 85: Factory Girl

Creating or Building Multiple Objects

Page 86: Factory Girl

Build a Shitload Of Objects

Page 87: Factory Girl

FactoryGirl.create_list(:model, 5)

Page 88: Factory Girl

FactoryGirl.build_list(:model, 5)

Page 89: Factory Girl

FactoryGirl.build_stubbed_list(:model, 5)

Page 90: Factory Girl

irb(main):001:0> FactoryGirl.create_list(:post, 5)

Page 91: Factory Girl

irb(main):001:0> FactoryGirl.create_list(:post, 5)=> [#<Post id: 1, title: “This is my post.”>, #<Post id: 2, title: “This is my post.”>, #<Post id: 3, title: “This is my post.”>, #<Post id: 4, title: “This is my post.”>, #<Post id: 5, title: “This is my post.”>]

Page 92: Factory Girl

Callbacks

Page 93: Factory Girl

Execute Arbitrary Code When Building & Creating

Page 94: Factory Girl

class User < ActiveRecord::Base has_many :postsend

app/models/user.rb

Page 95: Factory Girl

FactoryGirl.define do factory :user_with_posts do ignore do posts_count 5 end

after(:create) do |user, evaluator| FactoryGirl.create_list(:post, evaluator.posts_count, user: user) end endend

spec/factories/users.rb

Page 96: Factory Girl

irb(main):001:0> FactoryGirl.create(:user).posts.length=> 0

Page 97: Factory Girl

irb(main):001:0> FactoryGirl.create(:user_with_posts).posts.length=> 5

Page 98: Factory Girl

irb(main):001:0> FactoryGirl.create(:user_with_posts,posts_count: 15).posts.length=> 15

Page 99: Factory Girl

Wrapping Up...

Page 100: Factory Girl

Factory Girl is Magic

Page 101: Factory Girl

Easier to Maintain

Page 102: Factory Girl

Less of a Headache

Page 103: Factory Girl

Fun to Work With

Page 104: Factory Girl

Questions?