Factory Girl

11,093 views

Published on

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

3 Comments
24 Likes
Statistics
Notes
No Downloads
Views
Total views
11,093
On SlideShare
0
From Embeds
0
Number of Embeds
57
Actions
Shares
0
Downloads
141
Comments
3
Likes
24
Embeds 0
No embeds

No notes for slide

Factory Girl

  1. 1. Factory GirlA Brief Introduction Using Ruby on Rails
  2. 2. Factory GirlA Brief Introduction Using Ruby on Rails Yet Another Blog Example
  3. 3. What’s Factory Girl?
  4. 4. A Replacement for Fixtures
  5. 5. Provides a Simple DSL
  6. 6. Keeps TestsFocused & Readable
  7. 7. Builds Objects Instead of Database Records
  8. 8. Installation
  9. 9. Gemfile
  10. 10. Gemfilegroup :development, :test do gem ‘factory_girl_rails’end
  11. 11. $ bundle install
  12. 12. Defining a Factory
  13. 13. spec/factories/
  14. 14. spec/factories/users.rb
  15. 15. spec/factories/posts.rb
  16. 16. spec/factories/comments.rb
  17. 17. spec/factories/products.rb
  18. 18. spec/factories/users.rb
  19. 19. spec/factories/users.rb FactoryGirl.define do factory :user do name ‘Joe Blow’ email ‘joe.blow@example.com’ password ‘p@ssw0rd’ admin false end end
  20. 20. spec/models/user_spec.rb
  21. 21. spec/models/user_spec.rb describe User do end
  22. 22. spec/models/user_spec.rb describe User do subject { FactoryGirl.create(:user) } end
  23. 23. spec/models/user_spec.rb describe User do subject { FactoryGirl.create(:user) } its(:name) { should == ‘Joe Blow’ } end
  24. 24. spec/models/user_spec.rb describe User do subject { FactoryGirl.create(:user) } its(:name) { should == ‘Joe Blow’ } its(:email) { should == ‘joe.blow@example.com’ } end
  25. 25. spec/models/user_spec.rb describe User do subject { FactoryGirl.create(:user) } its(:name) { should == ‘Joe Blow’ } its(:email) { should == ‘joe.blow@example.com’ } it { should_not be_admin } end
  26. 26. FactoryGirl.create(:user)
  27. 27. FactoryGirl.build(:user)
  28. 28. FactoryGirl.build_stubbed(:user)
  29. 29. spec/spec_helper.rb
  30. 30. spec/spec_helper.rbRSpec.configure do |config| config.include FactoryGirl::Syntax::Methodsend
  31. 31. FactoryGirl.create(:user)
  32. 32. create(:user)
  33. 33. build(:user)
  34. 34. build_stubbed(:user)
  35. 35. spec/models/user_spec.rb describe User do subject { create(:user) } its(:name) { should == ‘Joe Blow’ } its(:email) { should == ‘joe.blow@example.com’ } it { should_not be_admin } end
  36. 36. Overriding Attributes
  37. 37. Keep Only Relevant Attributes in Tests
  38. 38. spec/models/user_spec.rb context ‘a duplicate email address’ do it { should_not be_valid } end
  39. 39. spec/models/user_spec.rb context ‘a duplicate email address’ do let(:first_user) { User.create(name: ‘Joe First’, email: ‘joe@example.com’, password: ‘test123’, admin: false) } subject { User.new(name: ‘Joe Duplicate’, email: first_user.email, password: ‘test123’, admin: false) } it { should_not be_valid } end
  40. 40. spec/models/user_spec.rb context ‘a duplicate email address’ do let(:user) { create(:user) } subject { build(:user, email: user.email) } it { should_not be_valid } end
  41. 41. Lazy Attributes
  42. 42. Lazy Attributes AreDynamic Attributes
  43. 43. 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 end end
  44. 44. irb(main):001:0> FactoryGirl.create(:post)
  45. 45. irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 1, title: “This is my post.”,content: “There are many like it, but this one ismine.”, published_at: 2012-12-20 23:47:34 UTC>
  46. 46. Gemfilegroup :development, :test do gem ‘factory_girl_rails’ gem ‘ffaker’end
  47. 47. spec/factories/posts.rb FactoryGirl.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } end end
  48. 48. irb(main):001:0> FactoryGirl.create(:post)
  49. 49. irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 2, title: “Lorem ipsum dolor sitamet, consectetur adipiscing elit.”, content:“Pellentesque adipiscing varius suscipit …”,published_at: 2012-12-20 23:48:14 UTC>
  50. 50. irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 3, title: “Nulla id augue ut maurispharetra tincidunt ac sed velit.”, content:“Nullam tincidunt, dolor quis pellentesque …”,published_at: 2012-12-20 23:49:06 UTC>
  51. 51. Sequences
  52. 52. Reuse Common Attributes
  53. 53. spec/factories/sequences.rbFactoryGirl.define do sequence :email do |n| “person#{n}@example.com” endend
  54. 54. spec/factories/users.rbFactoryGirl.define do factory :user do name { Faker::Name.name } email password ‘p@ssw0rd’ admin false endend
  55. 55. person1@example.com
  56. 56. person1@example.com,person2@example.com
  57. 57. person1@example.com,person2@example.com,person3@example.com
  58. 58. person1@example.com,person2@example.com,person3@example.com,etc.
  59. 59. Dependent Attributes
  60. 60. Attributes FromOther Attributes
  61. 61. spec/factories/users.rbFactoryGirl.define do factory :user do name ‘Joe Blow’ email ‘joe.blow@example.com’ password ‘p@ssw0rd’ admin false endend
  62. 62. spec/factories/users.rbFactoryGirl.define do factory :user do name ‘Joe Blow’ email { ‘#{name.gsub(/s/, ‘.’)}@example.com’.downcase } password ‘p@ssw0rd’ admin false endend
  63. 63. irb(main):001:0> FactoryGirl.create(:user)=> #<User id: 1, name: “Joe Blow”, email:“joe.blow@example.com”, password: “p@ssw0rd”, admin: false>
  64. 64. irb(main):001:0> FactoryGirl.create(:user, name: ‘Joe Mama’)=> #<User id: 2, name: “Joe Mama”, email:“joe.mama@example.com”, password: “p@ssw0rd”, admin: false>
  65. 65. Traits
  66. 66. Specify Types Of Factories
  67. 67. describe Post do context ‘an unpublished post’ do subject { create(:post, published_at: nil) } it ‘will never be read’ do # ... end endend
  68. 68. spec/factories/posts.rbFactoryGirl.define do factory :post do title { Faker::Lorem.sentence } content { Faker::Lorem.sentences.join(‘ ’) } published_at { Time.now } endend
  69. 69. spec/factories/posts.rbFactoryGirl.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
  70. 70. spec/models/post_spec.rbdescribe Post do context ‘an unpublished post’ do subject { create(:post, :unpublished) } it ‘will never be read’ do # ... end endend
  71. 71. Associations
  72. 72. Build Associated Objects From Factories
  73. 73. app/models/post.rbclass Post < ActiveRecord::Base belongs_to :userend
  74. 74. irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: …, title: “…”, content: “…”,published_at: …, user: nil>
  75. 75. spec/factories/posts.rbFactoryGirl.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
  76. 76. spec/factories/posts.rbFactoryGirl.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
  77. 77. irb(main):001:0> FactoryGirl.create(:post)=> #<Post …, user: #<User id: 123, name: “JohnWayne”, …>>
  78. 78. Transient Attributes
  79. 79. Customize BehaviorWith Fake Attributes
  80. 80. spec/factories/posts.rbFactoryGirl.define do factory :post do ignore do unapproved false end title { unapproved ? “ಠ_ಠ” : “This is my post.” } endend
  81. 81. spec/factories/posts.rbFactoryGirl.define do factory :post do ignore do unapproved false end title { unapproved ? “ಠ_ಠ” : “This is my post.” } endend
  82. 82. spec/factories/posts.rbFactoryGirl.define do factory :post do ignore do unapproved false end title { unapproved ? “ಠ_ಠ” : “This is my post.” } endend
  83. 83. irb(main):001:0> FactoryGirl.create(:post)=> #<Post id: 2, title: “This is my post.”>
  84. 84. irb(main):001:0> FactoryGirl.create(:post, unapproved: true)=> #<Post id: 2, title: “ಠ_ಠ”>
  85. 85. Creating or Building Multiple Objects
  86. 86. Build a Shitload Of Objects
  87. 87. FactoryGirl.create_list(:model, 5)
  88. 88. FactoryGirl.build_list(:model, 5)
  89. 89. FactoryGirl.build_stubbed_list(:model, 5)
  90. 90. irb(main):001:0> FactoryGirl.create_list(:post, 5)
  91. 91. 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 mypost.”>, #<Post id: 4, title: “This is my post.”>, #<Postid: 5, title: “This is my post.”>]
  92. 92. Callbacks
  93. 93. Execute Arbitrary CodeWhen Building & Creating
  94. 94. app/models/user.rbclass User < ActiveRecord::Base has_many :postsend
  95. 95. spec/factories/users.rbFactoryGirl.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
  96. 96. irb(main):001:0> FactoryGirl.create(:user).posts.length=> 0
  97. 97. irb(main):001:0> FactoryGirl.create(:user_with_posts).posts.length=> 5
  98. 98. irb(main):001:0> FactoryGirl.create(:user_with_posts,posts_count: 15).posts.length=> 15
  99. 99. Wrapping Up...
  100. 100. Factory Girl is Magic
  101. 101. Easier to Maintain
  102. 102. Less of a Headache
  103. 103. Fun to Work With
  104. 104. Questions?

×