Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1082 lines (826 sloc) 27.146 kb
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
1 Getting Started
2 ===============
3
38a571d Joshua Clayton Update getting started doc to outline updating gemfile
joshuaclayton authored
4 Update Your Gemfile
5 -------------------
6
4d4b5d9 Gabe Berke-Williams typo
gabebw authored
7 If you're using Rails, you'll need to change the required version of `factory_girl_rails`:
38a571d Joshua Clayton Update getting started doc to outline updating gemfile
joshuaclayton authored
8
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
9 ```ruby
e9d9e30 Joshua Clayton Prep for FactoryGirl 4.0
joshuaclayton authored
10 gem "factory_girl_rails", "~> 4.0"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
11 ```
38a571d Joshua Clayton Update getting started doc to outline updating gemfile
joshuaclayton authored
12
13 If you're *not* using Rails, you'll just have to change the required version of `factory_girl`:
14
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
15 ```ruby
e9d9e30 Joshua Clayton Prep for FactoryGirl 4.0
joshuaclayton authored
16 gem "factory_girl", "~> 4.0"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
17 ```
38a571d Joshua Clayton Update getting started doc to outline updating gemfile
joshuaclayton authored
18
d48b760 αλεx π Adding JRuby support to FactoryGirl
ifesdjeen authored
19 JRuby users: FactoryGirl works with JRuby starting with 1.6.7.2 (latest stable, as per July 2012).
20 JRuby has to be used in 1.9 mode, for that, use JRUBY_OPTS environment variable:
21
22 ```
23 export JRUBY_OPTS=--1.9
24 ```
25
38a571d Joshua Clayton Update getting started doc to outline updating gemfile
joshuaclayton authored
26 Once your Gemfile is updated, you'll want to update your bundle.
27
4a16f72 Joshua Clayton Add documentation about how to use FG without Rails/Bundler
joshuaclayton authored
28 Using Without Bundler
29 ---------------------
30
31 If you're not using Bundler, be sure to have the gem installed and call:
32
33 ```
34 require 'factory_girl'
35 ```
36
37 Once required, assuming you have a directory structure of `spec/factories` or
38 `test/factories`, all you'll need to do is run
39
40 ```ruby
41 FactoryGirl.find_definitions
42 ```
43
44 If you're using a separate directory structure for your factories, you can
45 change the definition file paths before trying to find definitions:
46
47 ```ruby
48 FactoryGirl.definition_file_paths = %w(custom_factories_directory)
49 FactoryGirl.find_definitions
50 ```
51
52 If you don't have a separate directory of factories and would like to define
53 them inline, that's possible as well:
54
55 ```ruby
56 require 'factory_girl'
57
58 FactoryGirl.define do
59 factory :user do
60 name 'John Doe'
61 date_of_birth { 21.years.ago }
62 end
63 end
64 ```
65
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
66 Defining factories
67 ------------------
68
69 Each factory has a name and a set of attributes. The name is used to guess the class of the object by default, but it's possible to explicitly specify it:
70
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
71 ```ruby
72 # This will guess the User class
73 FactoryGirl.define do
74 factory :user do
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
75 first_name "John"
76 last_name "Doe"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
77 admin false
78 end
79
80 # This will use the User class (Admin would have been guessed)
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
81 factory :admin, class: User do
82 first_name "Admin"
83 last_name "User"
84 admin true
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
85 end
86 end
87 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
88
89 It is highly recommended that you have one factory for each class that provides the simplest set of attributes necessary to create an instance of that class. If you're creating ActiveRecord objects, that means that you should only provide attributes that are required through validations and that do not have defaults. Other factories can be created through inheritance to cover common scenarios for each class.
90
91 Attempting to define multiple factories with the same name will raise an error.
92
93 Factories can be defined anywhere, but will be automatically loaded if they
94 are defined in files at the following locations:
95
96 test/factories.rb
97 spec/factories.rb
98 test/factories/*.rb
99 spec/factories/*.rb
100
101 Using factories
102 ---------------
103
4bc2bb1 Erik Ostrom Fixed reference to "stub" build strategy.
eostrom authored
104 factory\_girl supports several different build strategies: build, create, attributes\_for and build\_stubbed:
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
105
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
106 ```ruby
107 # Returns a User instance that's not saved
108 user = FactoryGirl.build(:user)
cbd42ed Joshua Clayton Whitespace
joshuaclayton authored
109
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
110 # Returns a saved User instance
111 user = FactoryGirl.create(:user)
cbd42ed Joshua Clayton Whitespace
joshuaclayton authored
112
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
113 # Returns a hash of attributes that can be used to build a User instance
114 attrs = FactoryGirl.attributes_for(:user)
cbd42ed Joshua Clayton Whitespace
joshuaclayton authored
115
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
116 # Returns an object with all defined attributes stubbed out
117 stub = FactoryGirl.build_stubbed(:user)
f32651d Justin Ko Calling the syntax methods with a block yields the return object. Closes...
justinko authored
118
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
119 # Passing a block to any of the methods above will yield the return object
120 FactoryGirl.create(:user) do |user|
121 user.posts.create(attributes_for(:post))
122 end
123 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
124
125 No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
126
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
127 ```ruby
128 # Build a User instance and override the first_name property
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
129 user = FactoryGirl.build(:user, first_name: "Joe")
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
130 user.first_name
131 # => "Joe"
132 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
133
134 If repeating "FactoryGirl" is too verbose for you, you can mix the syntax methods in:
135
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
136 ```ruby
137 # rspec
138 RSpec.configure do |config|
139 config.include FactoryGirl::Syntax::Methods
140 end
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
141
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
142 # Test::Unit
143 class Test::Unit::TestCase
266b1d6 Mike Subelsky Fix name of FactoryGirl::Syntax::Methods module in GETTING_STARTED.md
subelsky authored
144 include FactoryGirl::Syntax::Methods
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
145 end
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
146
147 # Cucumber
148 World(FactoryGirl::Syntax::Methods)
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
149 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
150
fa2b614 Joshua Clayton Be more explicit about what requiring FactoryGirl::Syntax::Methods does
joshuaclayton authored
151 This allows you to use the core set of syntax methods (`build`,
152 `build_stubbed`, `create`, `attributes_for`, and their `*_list` counterparts)
153 without having to call them on FactoryGirl directly:
4d83729 Joshua Clayton Documentation fixes
joshuaclayton authored
154
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
155 ```ruby
156 describe User, "#full_name" do
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
157 subject { create(:user, first_name: "John", last_name: "Doe") }
4d83729 Joshua Clayton Documentation fixes
joshuaclayton authored
158
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
159 its(:full_name) { should == "John Doe" }
160 end
161 ```
4d83729 Joshua Clayton Documentation fixes
joshuaclayton authored
162
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
163 Lazy Attributes
164 ---------------
165
67fc3bc Gabe Berke-Williams Whitespace, textwidth, and escaping underscores.
gabebw authored
166 Most factory attributes can be added using static values that are evaluated when
167 the factory is defined, but some attributes (such as associations and other
168 attributes that must be dynamically generated) will need values assigned each
169 time an instance is generated. These "lazy" attributes can be added by passing a
170 block instead of a parameter:
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
171
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
172 ```ruby
173 factory :user do
174 # ...
175 activation_code { User.generate_activation_code }
176 date_of_birth { 21.years.ago }
177 end
178 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
179
3768d15 Add documentation to using syntax methods inside dynamic attributes
Ben Zhang and Josh Clayton authored
180 In addition to running other methods dynamically, you can use FactoryGirl's
181 syntax methods (like `build`, `create`, and `generate`) within dynamic
182 attributes without having to prefix the call with `FactoryGirl.`. This allows
183 you to do:
184
185 ```ruby
186 sequence(:random_string) {|n| LoremIpsum.generate }
187
188 factory :post do
189 title { generate(:random_string) } # instead of FactoryGirl.generate(:random_string)
190 end
191
192 factory :comment do
193 post
194 body { generate(:random_string) } # instead of FactoryGirl.generate(:random_string)
195 end
196 ```
197
9e1024b Joshua Clayton More docs
joshuaclayton authored
198 Aliases
199 -------
200
201 Aliases allow you to use named associations more easily.
202
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
203 ```ruby
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
204 factory :user, aliases: [:author, :commenter] do
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
205 first_name "John"
206 last_name "Doe"
207 date_of_birth { 18.years.ago }
208 end
209
210 factory :post do
211 author
212 # instead of
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
213 # association :author, factory: :user
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
214 title "How to read a book effectively"
215 body "There are five steps involved."
216 end
217
218 factory :comment do
219 commenter
220 # instead of
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
221 # association :commenter, factory: :user
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
222 body "Great article!"
223 end
224 ```
9e1024b Joshua Clayton More docs
joshuaclayton authored
225
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
226 Dependent Attributes
227 --------------------
228
b79a525 Joshua Clayton Proxy => Strategy
joshuaclayton authored
229 Attributes can be based on the values of other attributes using the evaluator that is yielded to lazy attribute blocks:
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
230
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
231 ```ruby
232 factory :user do
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
233 first_name "Joe"
234 last_name "Blow"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
235 email { "#{first_name}.#{last_name}@example.com".downcase }
236 end
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
237
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
238 FactoryGirl.create(:user, last_name: "Doe").email
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
239 # => "joe.doe@example.com"
240 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
241
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
242 Transient Attributes
243 --------------------
244
245 There may be times where your code can be DRYed up by passing in transient attributes to factories.
246
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
247 ```ruby
248 factory :user do
249 ignore do
250 rockstar true
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
251 upcased false
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
252 end
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
253
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
254 name { "John Doe#{" - Rockstar" if rockstar}" }
255 email { "#{name.downcase}@example.com" }
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
256
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
257 after(:create) do |user, evaluator|
b79a525 Joshua Clayton Proxy => Strategy
joshuaclayton authored
258 user.name.upcase! if evaluator.upcased
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
259 end
260 end
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
261
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
262 FactoryGirl.create(:user, upcased: true).name
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
263 #=> "JOHN DOE - ROCKSTAR"
264 ```
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
265
67fc3bc Gabe Berke-Williams Whitespace, textwidth, and escaping underscores.
gabebw authored
266 Static and dynamic attributes can be ignored. Ignored attributes will be ignored
267 within attributes\_for and won't be set on the model, even if the attribute
268 exists or you attempt to override it.
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
269
40fc48d Prem Sichanugrist Fix FactoryGirl naming convention
sikachu authored
270 Within FactoryGirl's dynamic attributes, you can access ignored attributes as
271 you would expect. If you need to access the evaluator in a FactoryGirl callback,
b79a525 Joshua Clayton Proxy => Strategy
joshuaclayton authored
272 you'll need to declare a second block argument (for the evaluator) and access
67fc3bc Gabe Berke-Williams Whitespace, textwidth, and escaping underscores.
gabebw authored
273 ignored attributes from there.
c87429b Joshua Clayton Add transient variables
joshuaclayton authored
274
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
275 Associations
276 ------------
277
25affc7 Petteri Räty Typo fix possbile to possible
betelgeuse authored
278 It's possible to set up associations within factories. If the factory name is the same as the association name, the factory name can be left out.
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
279
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
280 ```ruby
281 factory :post do
282 # ...
283 author
284 end
285 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
286
287 You can also specify a different factory or override attributes:
288
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
289 ```ruby
290 factory :post do
291 # ...
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
292 association :author, factory: :user, last_name: "Writely"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
293 end
294 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
295
296 The behavior of the association method varies depending on the build strategy used for the parent object.
297
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
298 ```ruby
299 # Builds and saves a User and a Post
300 post = FactoryGirl.create(:post)
301 post.new_record? # => false
302 post.author.new_record? # => false
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
303
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
304 # Builds and saves a User, and then builds but does not save a Post
305 post = FactoryGirl.build(:post)
306 post.new_record? # => true
307 post.author.new_record? # => false
308 ```
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
309
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
310 To not save the associated object, specify strategy: :build in the factory:
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
311
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
312 ```ruby
313 factory :post do
314 # ...
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
315 association :author, factory: :user, strategy: :build
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
316 end
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
317
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
318 # Builds a User, and then builds a Post, but does not save either
319 post = FactoryGirl.build(:post)
320 post.new_record? # => true
321 post.author.new_record? # => true
322 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
323
9c6c252 Joshua Clayton Add tests and documentation for has_many relationships
joshuaclayton authored
324 Generating data for a `has_many` relationship is a bit more involved,
325 depending on the amount of flexibility desired, but here's a surefire example
326 of generating associated data.
327
328 ```ruby
329 FactoryGirl.define do
330
331 # post factory with a `belongs_to` association for the user
332 factory :post do
333 title "Through the Looking Glass"
334 user
335 end
336
337 # user factory without associated posts
338 factory :user do
339 name "John Doe"
340
341 # user_with_posts will create post data after the user has been created
342 factory :user_with_posts do
343 # posts_count is declared as an ignored attribute and available in
344 # attributes on the factory, as well as the callback via the evaluator
345 ignore do
346 posts_count 5
347 end
348
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
349 # the after(:create) yields two values; the user instance itself and the
9c6c252 Joshua Clayton Add tests and documentation for has_many relationships
joshuaclayton authored
350 # evaluator, which stores all values from the factory, including ignored
351 # attributes; `create_list`'s second argument is the number of records
352 # to create and we make sure the user is associated properly to the post
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
353 after(:create) do |user, evaluator|
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
354 FactoryGirl.create_list(:post, evaluator.posts_count, user: user)
9c6c252 Joshua Clayton Add tests and documentation for has_many relationships
joshuaclayton authored
355 end
356 end
357 end
358 end
359 ```
360
361 This allows us to do:
362
363 ```ruby
364 FactoryGirl.create(:user).posts.length # 0
365 FactoryGirl.create(:user_with_posts).posts.length # 5
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
366 FactoryGirl.create(:user_with_posts, posts_count: 15).posts.length # 15
9c6c252 Joshua Clayton Add tests and documentation for has_many relationships
joshuaclayton authored
367 ```
368
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
369 Inheritance
370 -----------
371
0c06997 Joshua Clayton Allow child factories to be defined by nesting
joshuaclayton authored
372 You can easily create multiple factories for the same class without repeating common attributes by nesting factories:
373
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
374 ```ruby
375 factory :post do
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
376 title "A title"
0c06997 Joshua Clayton Allow child factories to be defined by nesting
joshuaclayton authored
377
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
378 factory :approved_post do
379 approved true
380 end
381 end
0c06997 Joshua Clayton Allow child factories to be defined by nesting
joshuaclayton authored
382
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
383 approved_post = FactoryGirl.create(:approved_post)
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
384 approved_post.title # => "A title"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
385 approved_post.approved # => true
386 ```
0c06997 Joshua Clayton Allow child factories to be defined by nesting
joshuaclayton authored
387
388 You can also assign the parent explicitly:
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
389
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
390 ```ruby
391 factory :post do
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
392 title "A title"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
393 end
cbd42ed Joshua Clayton Whitespace
joshuaclayton authored
394
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
395 factory :approved_post, parent: :post do
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
396 approved true
397 end
398 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
399
67fc3bc Gabe Berke-Williams Whitespace, textwidth, and escaping underscores.
gabebw authored
400 As mentioned above, it's good practice to define a basic factory for each class
401 with only the attributes required to create it. Then, create more specific
402 factories that inherit from this basic parent. Factory definitions are still
403 code, so keep them DRY.
90ea1fe Ben Orenstein Copy edit GETTING_STARTED. Improve language, examples, and formatting.
r00k authored
404
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
405 Sequences
406 ---------
407
408 Unique values in a specific format (for example, e-mail addresses) can be
409 generated using sequences. Sequences are defined by calling sequence in a
410 definition block, and values in a sequence are generated by calling
8af12f0 Tom Stuart Replace Factory.next with FactoryGirl.generate in Getting Started guide
tomstuart authored
411 FactoryGirl.generate:
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
412
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
413 ```ruby
414 # Defines a new sequence
415 FactoryGirl.define do
416 sequence :email do |n|
417 "person#{n}@example.com"
418 end
419 end
cbd42ed Joshua Clayton Whitespace
joshuaclayton authored
420
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
421 FactoryGirl.generate :email
422 # => "person1@example.com"
cbd42ed Joshua Clayton Whitespace
joshuaclayton authored
423
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
424 FactoryGirl.generate :email
425 # => "person2@example.com"
426 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
427
428 Sequences can be used as attributes:
429
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
430 ```ruby
431 factory :user do
432 email
433 end
434 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
435
436 Or in lazy attributes:
437
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
438 ```ruby
439 factory :invite do
3768d15 Add documentation to using syntax methods inside dynamic attributes
Ben Zhang and Josh Clayton authored
440 invitee { generate(:email) }
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
441 end
442 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
443
444 And it's also possible to define an in-line sequence that is only used in
445 a particular factory:
446
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
447 ```ruby
448 factory :user do
449 sequence(:email) {|n| "person#{n}@example.com" }
450 end
451 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
452
71dacea Joshua Clayton Update the sequence documentation
joshuaclayton authored
453 You can also override the initial value:
454
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
455 ```ruby
456 factory :user do
457 sequence(:email, 1000) {|n| "person#{n}@example.com" }
458 end
459 ```
71dacea Joshua Clayton Update the sequence documentation
joshuaclayton authored
460
461 Without a block, the value will increment itself, starting at its initial value:
462
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
463 ```ruby
464 factory :post do
465 sequence(:position)
466 end
467 ```
71dacea Joshua Clayton Update the sequence documentation
joshuaclayton authored
468
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
469 Sequences can also have aliases. The sequence aliases share the same counter:
470
471 ```ruby
472 factory :user do
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
473 sequence(:email, 1000, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
474 end
475
476 # will increase value counter for :email which is shared by :sender and :receiver
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
477 FactoryGirl.next(:sender)
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
478 ```
479
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
480 Define aliases and use default value (1) for the counter
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
481
482 ```ruby
483 factory :user do
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
484 sequence(:email, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
485 end
486 ```
487
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
488 Setting the value:
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
489
490 ```ruby
491 factory :user do
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
492 sequence(:email, 'a', aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
493 end
494 ```
495
4ef98ff Joshua Clayton Clean up
joshuaclayton authored
496 The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
f013335 Kristian Mandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
497
1c74d9d Joshua Clayton Rename attribute groups to traits
joshuaclayton authored
498 Traits
499 ------
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
500
1c74d9d Joshua Clayton Rename attribute groups to traits
joshuaclayton authored
501 Traits allow you to group attributes together and then apply them
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
502 to any factory.
503
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
504 ```ruby
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
505 factory :user, aliases: [:author]
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
506
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
507 factory :story do
508 title "My awesome story"
509 author
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
510
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
511 trait :published do
512 published true
513 end
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
514
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
515 trait :unpublished do
516 published false
517 end
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
518
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
519 trait :week_long_publishing do
520 start_at { 1.week.ago }
521 end_at { Time.now }
522 end
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
523
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
524 trait :month_long_publishing do
525 start_at { 1.month.ago }
526 end_at { Time.now }
527 end
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
528
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
529 factory :week_long_published_story, traits: [:published, :week_long_publishing]
530 factory :month_long_published_story, traits: [:published, :month_long_publishing]
531 factory :week_long_unpublished_story, traits: [:unpublished, :week_long_publishing]
532 factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
533 end
534 ```
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
535
1c74d9d Joshua Clayton Rename attribute groups to traits
joshuaclayton authored
536 Traits can be used as attributes:
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
537
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
538 ```ruby
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
539 factory :week_long_published_story_with_title, parent: :story do
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
540 published
541 week_long_publishing
542 title { "Publishing that was started at {start_at}" }
543 end
544 ```
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
545
1c74d9d Joshua Clayton Rename attribute groups to traits
joshuaclayton authored
546 Traits that define the same attributes won't raise AttributeDefinitionErrors;
547 the trait that defines the attribute latest gets precedence.
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
548
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
549 ```ruby
550 factory :user do
551 name "Friendly User"
552 login { name }
553
554 trait :male do
555 name "John Doe"
556 gender "Male"
557 login { "#{name} (M)" }
558 end
559
560 trait :female do
561 name "Jane Doe"
562 gender "Female"
563 login { "#{name} (F)" }
564 end
565
566 trait :admin do
567 admin true
568 login { "admin-#{name}" }
569 end
570
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
571 factory :male_admin, traits: [:male, :admin] # login will be "admin-John Doe"
572 factory :female_admin, traits: [:admin, :female] # login will be "Jane Doe (F)"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
573 end
574 ```
86125a4 Joshua Clayton Document attribute groups
joshuaclayton authored
575
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
576 You can also override individual attributes granted by a trait in subclasses.
577
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
578 ```ruby
579 factory :user do
580 name "Friendly User"
581 login { name }
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
582
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
583 trait :male do
584 name "John Doe"
585 gender "Male"
586 login { "#{name} (M)" }
587 end
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
588
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
589 factory :brandon do
590 male
591 name "Brandon"
592 end
593 end
594 ```
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
595
442ba18 Joshua Clayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
596 Traits can also be passed in as a list of symbols when you construct an instance from FactoryGirl.
597
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
598 ```ruby
599 factory :user do
600 name "Friendly User"
442ba18 Joshua Clayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
601
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
602 trait :male do
603 name "John Doe"
604 gender "Male"
605 end
442ba18 Joshua Clayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
606
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
607 trait :admin do
608 admin true
609 end
610 end
442ba18 Joshua Clayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
611
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
612 # creates an admin user with gender "Male" and name "Jon Snow"
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
613 FactoryGirl.create(:user, :admin, :male, name: "Jon Snow")
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
614 ```
442ba18 Joshua Clayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
615
616 This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
617
13129b0 Simone Carletti Document build_list and create_list with runtime traits.
weppos authored
618 `create_list` and `build_list` methods are supported as well. Just remember to pass
619 the number of instances to create/build as second parameter, as documented in the
620 "Building or Creating Multiple Records" section of this file.
621
622 ```ruby
623 factory :user do
624 name "Friendly User"
625
626 trait :admin do
627 admin true
628 end
629 end
630
631 # creates 3 admin users with gender "Male" and name "Jon Snow"
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
632 FactoryGirl.create_list(:user, 3, :admin, :male, name: "Jon Snow")
13129b0 Simone Carletti Document build_list and create_list with runtime traits.
weppos authored
633 ```
634
c9ed3d8 Joshua Clayton Improve ability to define associations with traits and add documentation
joshuaclayton authored
635 Traits can be used with associations easily too:
13129b0 Simone Carletti Document build_list and create_list with runtime traits.
weppos authored
636
c9ed3d8 Joshua Clayton Improve ability to define associations with traits and add documentation
joshuaclayton authored
637 ```ruby
638 factory :user do
639 name "Friendly User"
640
641 trait :admin do
642 admin true
643 end
644 end
645
646 factory :post do
647 association :user, :admin, name: 'John Doe'
648 end
649
650 # creates an admin user with named "John Doe"
651 FactoryGirl.create(:post).user
652 ```
653
654 When you're using association names that're different than the factory:
655
656 ```ruby
657 factory :user do
658 name "Friendly User"
659
660 trait :admin do
661 admin true
662 end
663 end
664
665 factory :post do
666 association :author, :admin, factory: :user, name: 'John Doe'
667 # or
668 association :author, factory: [:user, :admin], name: 'John Doe'
669 end
670
671 # creates an admin user with named "John Doe"
672 FactoryGirl.create(:post).user
673 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
674 Callbacks
675 ---------
676
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
677 factory\_girl makes available four callbacks for injecting some code:
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
678
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
679 * after(:build) - called after a factory is built (via `FactoryGirl.build`, `FactoryGirl.create`)
680 * before(:create) - called before a factory is saved (via `FactoryGirl.create`)
681 * after(:create) - called after a factory is saved (via `FactoryGirl.create`)
682 * after(:stub) - called after a factory is stubbed (via `FactoryGirl.build_stubbed`)
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
683
684 Examples:
685
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
686 ```ruby
687 # Define a factory that calls the generate_hashed_password method after it is built
688 factory :user do
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
689 after(:build) { |user| generate_hashed_password(user) }
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
690 end
691 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
692
4d83729 Joshua Clayton Documentation fixes
joshuaclayton authored
693 Note that you'll have an instance of the user in the block. This can be useful.
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
694
695 You can also define multiple types of callbacks on the same factory:
696
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
697 ```ruby
698 factory :user do
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
699 after(:build) { |user| do_something_to(user) }
700 after(:create) { |user| do_something_else_to(user) }
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
701 end
702 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
703
704 Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
705
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
706 ```ruby
707 factory :user do
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
708 after(:create) { this_runs_first }
709 after(:create) { then_this }
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
710 end
711 ```
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
712
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
713 Calling FactoryGirl.create will invoke both `after_build` and `after_create` callbacks.
3acd41d Joe Ferris Extract examples out to a different file so that the readme people see o...
jferris authored
714
715 Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
716
f92195f Joshua Clayton Support binding a block to multiple callbacks
joshuaclayton authored
717 Multiple callbacks can be assigned to run a block; this is useful when building various strategies that run the same code (since there are no callbacks that are shared across all strategies).
718
719 ```ruby
720 factory :user do
721 callback(:after_stub, :before_create) { do_something }
722 after(:stub, :create) { do_something_else }
723 before(:create, :custom) { do_a_third_thing }
724 end
725 ```
726
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
727 Modifying factories
728 -------------------
729
730 If you're given a set of factories (say, from a gem developer) but want to change them to fit into your application better, you can
731 modify that factory instead of creating a child factory and adding attributes there.
732
733 If a gem were to give you a User factory:
734
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
735 ```ruby
736 FactoryGirl.define do
737 factory :user do
738 full_name "John Doe"
739 sequence(:username) {|n| "user#{n}" }
740 password "password"
741 end
742 end
743 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
744
745 Instead of creating a child factory that added additional attributes:
746
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
747 ```ruby
748 FactoryGirl.define do
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
749 factory :application_user, parent: :user do
b6692b6 Joshua Clayton Don't actually advocate using Faker to generate test data
joshuaclayton authored
750 full_name "Jane Doe"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
751 date_of_birth { 21.years.ago }
752 gender "Female"
753 health 90
754 end
755 end
756 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
757
758 You could modify that factory instead.
759
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
760 ```ruby
761 FactoryGirl.modify do
762 factory :user do
b6692b6 Joshua Clayton Don't actually advocate using Faker to generate test data
joshuaclayton authored
763 full_name "Jane Doe"
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
764 date_of_birth { 21.years.ago }
765 gender "Female"
766 health 90
767 end
768 end
769 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
770
771 When modifying a factory, you can change any of the attributes you want (aside from callbacks).
772
773 `FactoryGirl.modify` must be called outside of a `FactoryGirl.define` block as it operates on factories differently.
774
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
775 A caveat: you can only modify factories (not sequences or traits) and callbacks *still compound as they normally would*. So, if
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
776 the factory you're modifying defines an `after(:create)` callback, you defining an `after(:create)` won't override it, it'll just get run after the first callback.
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
777
dd7aa22 Colin Gemmell Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
778 Building or Creating Multiple Records
779 -------------------------------------
780
781 Sometimes, you'll want to create or build multiple instances of a factory at once.
782
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
783 ```ruby
784 built_users = FactoryGirl.build_list(:user, 25)
785 created_users = FactoryGirl.create_list(:user, 25)
786 ```
dd7aa22 Colin Gemmell Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
787
788 These methods will build or create a specific amount of factories and return them as an array.
789 To set the attributes for each of the factories, you can pass in a hash as you normally would.
790
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
791 ```ruby
055c976 Joshua Clayton Update getting started style
joshuaclayton authored
792 twenty_year_olds = FactoryGirl.build_list(:user, 25, date_of_birth: 20.years.ago)
1e82889 Daniel Schierbeck Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
793 ```
dd7aa22 Colin Gemmell Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
794
5780364 Joshua Clayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
795 Custom Construction
796 -------------------
797
ea89aad Joe Ferris Update README with more to_initialize info
jferris authored
798 If you want to use factory_girl to construct an object where some attributes
799 are passed to `initialize` or if you want to do something other than simply
800 calling `new` on your build class, you can override the default behavior by
4682ab0 Mark Rushakoff fix typo in GETTING_STARTED
mark-rushakoff authored
801 defining `initialize_with` on your factory. Example:
5780364 Joshua Clayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
802
803 ```ruby
804 # user.rb
805 class User
806 attr_accessor :name, :email
807
808 def initialize(name)
809 @name = name
810 end
811 end
812
813 # factories.rb
814 sequence(:name) {|n| "person#{n}@example.com" }
815
816 factory :user do
817 ignore do
b6692b6 Joshua Clayton Don't actually advocate using Faker to generate test data
joshuaclayton authored
818 name "Jane Doe"
5780364 Joshua Clayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
819 end
820
821 email
9907826 Joshua Clayton Base class is implied when calling .new within initialize_with
joshuaclayton authored
822 initialize_with { new(name) }
5780364 Joshua Clayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
823 end
824
b6692b6 Joshua Clayton Don't actually advocate using Faker to generate test data
joshuaclayton authored
825 FactoryGirl.build(:user).name # Jane Doe
5780364 Joshua Clayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
826 ```
827
828 Notice that I ignored the `name` attribute. If you don't want attributes
829 reassigned after your object has been instantiated, you'll want to `ignore` them.
830
ea89aad Joe Ferris Update README with more to_initialize info
jferris authored
831 Although factory_girl is written to work with ActiveRecord out of the box, it
832 can also work with any Ruby class. For maximum compatibiltiy with ActiveRecord,
833 the default initializer builds all instances by calling new on your build class
834 without any arguments. It then calls attribute writer methods to assign all the
835 attribute values. While that works fine for ActiveRecord, it actually doesn't
836 work for almost any other Ruby class.
837
838 You can override the initializer in order to:
839
840 * Build non-ActiveRecord objects that require arguments to `initialize`
841 * Use a method other than `new` to instantiate the instance
842 * Do crazy things like decorate the instance after it's built
843
9907826 Joshua Clayton Base class is implied when calling .new within initialize_with
joshuaclayton authored
844 When using `initialize_with`, you don't have to declare the class itself when
845 calling `new`; however, any other class methods you want to call will have to
846 be called on the class explicitly.
847
848 For example:
849
850 ```ruby
851 factory :user do
852 ignore do
b6692b6 Joshua Clayton Don't actually advocate using Faker to generate test data
joshuaclayton authored
853 name "John Doe"
9907826 Joshua Clayton Base class is implied when calling .new within initialize_with
joshuaclayton authored
854 end
855
856 initialize_with { User.build_with_name(name) }
857 end
858 ```
859
2b50190 Joshua Clayton Make hash of public attributes available within the initialize_with bloc...
joshuaclayton authored
860 You can also access all public attributes within the `initialize_with` block
861 by calling `attributes`:
862
863 ```ruby
864 factory :user do
865 ignore do
866 comments_count 5
867 end
868
b6692b6 Joshua Clayton Don't actually advocate using Faker to generate test data
joshuaclayton authored
869 name "John Doe"
2b50190 Joshua Clayton Make hash of public attributes available within the initialize_with bloc...
joshuaclayton authored
870
871 initialize_with { new(attributes) }
872 end
873 ```
874
875 This will build a hash of all attributes to be passed to `new`. It won't
876 include ignored attributes, but everything else defined in the factory will be
877 passed (associations, evalued sequences, etc.)
878
2f8731d Joshua Clayton Allow initialize_with defined for all factories
joshuaclayton authored
879 You can define `initialize_with` for all factories by including it in the
880 `FactoryGirl.define` block:
881
882 ```ruby
883 FactoryGirl.define do
884 initialize_with { new("Awesome first argument") }
885 end
886 ```
887
e9d9e30 Joshua Clayton Prep for FactoryGirl 4.0
joshuaclayton authored
888 When using `initialize_with`, attributes accessed from within the `initialize_with`
889 block are assigned *only* in the constructor; this equates to roughly the
890 following code:
a5b3a97 Joshua Clayton Optionally disable duplicate assignment of attributes in initialize_with
joshuaclayton authored
891
e9d9e30 Joshua Clayton Prep for FactoryGirl 4.0
joshuaclayton authored
892 ```ruby
893 FactoryGirl.define do
894 factory :user do
895 initialize_with { new(name) }
896
897 name { 'value' }
898 end
899 end
900
901 FactoryGirl.build(:user)
902 # runs
903 User.new('value')
904 ```
905
906 This prevents duplicate assignment; in versions of FactoryGirl before 4.0, it
907 would run this:
a5b3a97 Joshua Clayton Optionally disable duplicate assignment of attributes in initialize_with
joshuaclayton authored
908
e9d9e30 Joshua Clayton Prep for FactoryGirl 4.0
joshuaclayton authored
909 ```ruby
910 FactoryGirl.define do
911 factory :user do
912 initialize_with { new(name) }
913
914 name { 'value' }
915 end
916 end
917
918 FactoryGirl.build(:user)
919 # runs
920 user = User.new('value')
921 user.name = 'value'
922 ```
a5b3a97 Joshua Clayton Optionally disable duplicate assignment of attributes in initialize_with
joshuaclayton authored
923
c8c1a80 Joshua Clayton Add ability to register custom strategies
joshuaclayton authored
924 Custom Strategies
925 -----------------
926
927 There are times where you may want to extend behavior of factory\_girl by
928 adding a custom build strategy.
929
930 Strategies define two methods: `association` and `result`. `association`
931 receives a `FactoryGirl::FactoryRunner` instance, upon which you can call
932 `run`, overriding the strategy if you want. The second method, `result`,
933 receives a `FactoryGirl::Evaluation` instance. It provides a way to trigger
934 callbacks (with `notify`), `object` or `hash` (to get the result instance or a
935 hash based on the attributes defined in the factory), and `create`, which
936 executes the `to_create` callback defined on the factory.
937
938 To understand how factory\_girl uses strategies internally, it's probably
939 easiest to just view the source for each of the four default strategies.
940
bb00c91 Joshua Clayton Fix documentation around using composition with an existing strategy
joshuaclayton authored
941 Here's an example of composing a strategy using
c8c1a80 Joshua Clayton Add ability to register custom strategies
joshuaclayton authored
942 `FactoryGirl::Strategy::Create` to build a JSON representation of your model.
943
944 ```ruby
3a99005 Joshua Clayton Favor composition over inheritance for the JsonStrategy example
joshuaclayton authored
945 class JsonStrategy
946 def initialize
947 @strategy = FactoryGirl.strategy_by_name(:create).new
948 end
949
950 delegate :association, to: :@strategy
951
c8c1a80 Joshua Clayton Add ability to register custom strategies
joshuaclayton authored
952 def result(evaluation)
3a99005 Joshua Clayton Favor composition over inheritance for the JsonStrategy example
joshuaclayton authored
953 @strategy.result(evaluation).to_json
c8c1a80 Joshua Clayton Add ability to register custom strategies
joshuaclayton authored
954 end
955 end
956 ```
957
958 For factory\_girl to recognize the new strategy, you can register it:
959
960 ```ruby
961 FactoryGirl.register_strategy(:json, JsonStrategy)
962 ```
963
964 This allows you to call
965
966 ```ruby
967 FactoryGirl.json(:user)
968 ```
969
970 Finally, you can override factory\_girl's own strategies if you'd like by
971 registering a new object in place of the strategies.
972
bef5a01 Introduce new callback syntax
Josh Clayton and Jason Draper authored
973 Custom Callbacks
974 ----------------
975
976 Custom callbacks can be defined if you're using custom strategies:
977
978 ```ruby
979 class JsonStrategy
980 def initialize
981 @strategy = FactoryGirl.strategy_by_name(:create).new
982 end
983
984 delegate :association, to: :@strategy
985
986 def result(evaluation)
987 result = @strategy.result(evaluation)
988 evaluation.notify(:before_json, result)
989
990 result.to_json.tap do |json|
991 evaluation.notify(:after_json, json)
992 evaluation.notify(:make_json_awesome, json)
993 end
994 end
995 end
996
997 FactoryGirl.register_strategy(:json, JsonStrategy)
998
999 FactoryGirl.define do
1000 factory :user do
1001 before(:json) {|user| do_something_to(user) }
1002 after(:json) {|user_json| do_something_to(user_json) }
1003 callback(:make_json_awesome) {|user_json| do_something_to(user_json) }
1004 end
1005 end
1006 ```
1007
351b04d Joshua Clayton Allow a user to skip the default create execution
joshuaclayton authored
1008 Custom Methods to Persist Objects
95b88ac Joshua Clayton Fix dashes
joshuaclayton authored
1009 ---------------------------------
351b04d Joshua Clayton Allow a user to skip the default create execution
joshuaclayton authored
1010
1011 By default, creating a record will call `save!` on the instance; since this
1012 may not always be ideal, you can override that behavior by defining
1013 `to_create` on the factory:
1014
1015 ```ruby
1016 factory :different_orm_model do
1017 to_create {|instance| instance.persist! }
1018 end
1019 ```
1020
1021 To disable the persistence method altogether on create, you can `skip_create`
1022 for that factory:
1023
1024 ```ruby
1025 factory :user_without_database do
1026 skip_create
1027 end
1028 ```
1029
f7efc61 Joshua Clayton Allow to_create defined for all factories
joshuaclayton authored
1030 To override `to_create` for all factories, define it within the
1031 `FactoryGirl.define` block:
1032
1033 ```ruby
1034 FactoryGirl.define do
1035 to_create {|instance| instance.persist! }
1036
1037
1038 factory :user do
1039 name "John Doe"
1040 end
1041 end
1042 ```
1043
925a947 Joshua Clayton Use ActiveSupport::Notifications for pub/sub of factory usage
joshuaclayton authored
1044 ActiveSupport Instrumentation
1045 -----------------------------
1046
1047 In order to track what factories are created (and with what build strategy),
1048 `ActiveSupport::Notifications` are included to provide a way to subscribe to
1049 factories being run. One example would be to track factories based on a
1050 threshold of execution time.
1051
1052 ```ruby
1053 ActiveSupport::Notifications.subscribe("factory_girl.run_factory") do |name, start, finish, id, payload|
1054 execution_time_in_seconds = finish - start
1055
1056 if execution_time_in_seconds >= 0.5
1057 $stderr.puts "Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}"
1058 end
1059 end
1060 ```
1061
1062 Another example would be tracking all factories and how they're used
1063 throughout your test suite. If you're using RSpec, it's as simple as adding a
1064 `before(:suite)` and `after(:suite)`:
1065
1066 ```ruby
1067 config.before(:suite) do
1068 @factory_girl_results = {}
1069 ActiveSupport::Notifications.subscribe("factory_girl.run_factory") do |name, start, finish, id, payload|
1070 factory_name = payload[:name]
1071 strategy_name = payload[:strategy]
1072 @factory_girl_results[factory_name] ||= {}
1073 @factory_girl_results[factory_name][strategy_name] ||= 0
1074 @factory_girl_results[factory_name][strategy_name] += 1
1075 end
1076 end
1077
1078 config.after(:suite) do
1079 puts @factory_girl_results
1080 end
1081 ```
Something went wrong with that request. Please try again.