Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 761 lines (578 sloc) 19.201 kb
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
1 Getting Started
2 ===============
3
38a571d @joshuaclayton Update getting started doc to outline updating gemfile
joshuaclayton authored
4 Update Your Gemfile
5 -------------------
6
4d4b5d9 @gabebw typo
gabebw authored
7 If you're using Rails, you'll need to change the required version of `factory_girl_rails`:
38a571d @joshuaclayton Update getting started doc to outline updating gemfile
joshuaclayton authored
8
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
9 ```ruby
4c42749 @joshuaclayton Update GETTING_STARTED to reflect factory_girl_rails mirroring factory_g...
joshuaclayton authored
10 gem "factory_girl_rails", "~> 3.0"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
11 ```
38a571d @joshuaclayton 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 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
15 ```ruby
cfaa00c @joshuaclayton Remove Rails 2 support
joshuaclayton authored
16 gem "factory_girl", "~> 3.0"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
17 ```
38a571d @joshuaclayton Update getting started doc to outline updating gemfile
joshuaclayton authored
18
19 Once your Gemfile is updated, you'll want to update your bundle.
20
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
21 Defining factories
22 ------------------
23
24 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:
25
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
26 ```ruby
27 # This will guess the User class
28 FactoryGirl.define do
29 factory :user do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
30 first_name "John"
31 last_name "Doe"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
32 admin false
33 end
34
35 # This will use the User class (Admin would have been guessed)
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
36 factory :admin, class: User do
37 first_name "Admin"
38 last_name "User"
39 admin true
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
40 end
41 end
42 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
43
44 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.
45
46 Attempting to define multiple factories with the same name will raise an error.
47
48 Factories can be defined anywhere, but will be automatically loaded if they
49 are defined in files at the following locations:
50
51 test/factories.rb
52 spec/factories.rb
53 test/factories/*.rb
54 spec/factories/*.rb
55
56 Using factories
57 ---------------
58
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
59 factory\_girl supports several different build strategies: build, create, attributes\_for and stub:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
60
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
61 ```ruby
62 # Returns a User instance that's not saved
63 user = FactoryGirl.build(:user)
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
64
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
65 # Returns a saved User instance
66 user = FactoryGirl.create(:user)
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
67
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
68 # Returns a hash of attributes that can be used to build a User instance
69 attrs = FactoryGirl.attributes_for(:user)
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
70
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
71 # Returns an object with all defined attributes stubbed out
72 stub = FactoryGirl.build_stubbed(:user)
f32651d @justinko Calling the syntax methods with a block yields the return object. Closes...
justinko authored
73
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
74 # Passing a block to any of the methods above will yield the return object
75 FactoryGirl.create(:user) do |user|
76 user.posts.create(attributes_for(:post))
77 end
78 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
79
80 No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
81
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
82 ```ruby
83 # Build a User instance and override the first_name property
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
84 user = FactoryGirl.build(:user, first_name: "Joe")
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
85 user.first_name
86 # => "Joe"
87 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
88
89 If repeating "FactoryGirl" is too verbose for you, you can mix the syntax methods in:
90
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
91 ```ruby
92 # rspec
93 RSpec.configure do |config|
94 config.include FactoryGirl::Syntax::Methods
95 end
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
96
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
97 # Test::Unit
98 class Test::Unit::TestCase
266b1d6 @subelsky Fix name of FactoryGirl::Syntax::Methods module in GETTING_STARTED.md
subelsky authored
99 include FactoryGirl::Syntax::Methods
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
100 end
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
101
102 # Cucumber
103 World(FactoryGirl::Syntax::Methods)
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
104 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
105
4d83729 @joshuaclayton Documentation fixes
joshuaclayton authored
106 This would allow you to write:
107
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
108 ```ruby
109 describe User, "#full_name" do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
110 subject { create(:user, first_name: "John", last_name: "Doe") }
4d83729 @joshuaclayton Documentation fixes
joshuaclayton authored
111
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
112 its(:full_name) { should == "John Doe" }
113 end
114 ```
4d83729 @joshuaclayton Documentation fixes
joshuaclayton authored
115
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
116 Lazy Attributes
117 ---------------
118
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
119 Most factory attributes can be added using static values that are evaluated when
120 the factory is defined, but some attributes (such as associations and other
121 attributes that must be dynamically generated) will need values assigned each
122 time an instance is generated. These "lazy" attributes can be added by passing a
123 block instead of a parameter:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
124
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
125 ```ruby
126 factory :user do
127 # ...
128 activation_code { User.generate_activation_code }
129 date_of_birth { 21.years.ago }
130 end
131 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
132
9e1024b @joshuaclayton More docs
joshuaclayton authored
133 Aliases
134 -------
135
136 Aliases allow you to use named associations more easily.
137
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
138 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
139 factory :user, aliases: [:author, :commenter] do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
140 first_name "John"
141 last_name "Doe"
142 date_of_birth { 18.years.ago }
143 end
144
145 factory :post do
146 author
147 # instead of
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
148 # association :author, factory: :user
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
149 title "How to read a book effectively"
150 body "There are five steps involved."
151 end
152
153 factory :comment do
154 commenter
155 # instead of
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
156 # association :commenter, factory: :user
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
157 body "Great article!"
158 end
159 ```
9e1024b @joshuaclayton More docs
joshuaclayton authored
160
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
161 Dependent Attributes
162 --------------------
163
b79a525 @joshuaclayton Proxy => Strategy
joshuaclayton authored
164 Attributes can be based on the values of other attributes using the evaluator that is yielded to lazy attribute blocks:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
165
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
166 ```ruby
167 factory :user do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
168 first_name "Joe"
169 last_name "Blow"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
170 email { "#{first_name}.#{last_name}@example.com".downcase }
171 end
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
172
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
173 FactoryGirl.create(:user, last_name: "Doe").email
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
174 # => "joe.doe@example.com"
175 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
176
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
177 Transient Attributes
178 --------------------
179
180 There may be times where your code can be DRYed up by passing in transient attributes to factories.
181
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
182 ```ruby
183 factory :user do
184 ignore do
185 rockstar true
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
186 upcased false
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
187 end
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
188
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
189 name { "John Doe#{" - Rockstar" if rockstar}" }
190 email { "#{name.downcase}@example.com" }
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
191
b79a525 @joshuaclayton Proxy => Strategy
joshuaclayton authored
192 after_create do |user, evaluator|
193 user.name.upcase! if evaluator.upcased
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
194 end
195 end
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
196
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
197 FactoryGirl.create(:user, upcased: true).name
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
198 #=> "JOHN DOE - ROCKSTAR"
199 ```
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
200
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
201 Static and dynamic attributes can be ignored. Ignored attributes will be ignored
202 within attributes\_for and won't be set on the model, even if the attribute
203 exists or you attempt to override it.
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
204
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
205 Within Factory Girl's dynamic attributes, you can access ignored attributes as
b79a525 @joshuaclayton Proxy => Strategy
joshuaclayton authored
206 you would expect. If you need to access the evaluator in a Factory Girl callback,
207 you'll need to declare a second block argument (for the evaluator) and access
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
208 ignored attributes from there.
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
209
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
210 Associations
211 ------------
212
25affc7 @betelgeuse Typo fix possbile to possible
betelgeuse authored
213 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 @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
214
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
215 ```ruby
216 factory :post do
217 # ...
218 author
219 end
220 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
221
222 You can also specify a different factory or override attributes:
223
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
224 ```ruby
225 factory :post do
226 # ...
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
227 association :author, factory: :user, last_name: "Writely"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
228 end
229 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
230
231 The behavior of the association method varies depending on the build strategy used for the parent object.
232
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
233 ```ruby
234 # Builds and saves a User and a Post
235 post = FactoryGirl.create(:post)
236 post.new_record? # => false
237 post.author.new_record? # => false
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
238
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
239 # Builds and saves a User, and then builds but does not save a Post
240 post = FactoryGirl.build(:post)
241 post.new_record? # => true
242 post.author.new_record? # => false
243 ```
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
244
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
245 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
246
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
247 ```ruby
248 factory :post do
249 # ...
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
250 association :author, factory: :user, strategy: :build
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
251 end
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
252
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
253 # Builds a User, and then builds a Post, but does not save either
254 post = FactoryGirl.build(:post)
255 post.new_record? # => true
256 post.author.new_record? # => true
257 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
258
9c6c252 @joshuaclayton Add tests and documentation for has_many relationships
joshuaclayton authored
259 Generating data for a `has_many` relationship is a bit more involved,
260 depending on the amount of flexibility desired, but here's a surefire example
261 of generating associated data.
262
263 ```ruby
264 FactoryGirl.define do
265
266 # post factory with a `belongs_to` association for the user
267 factory :post do
268 title "Through the Looking Glass"
269 user
270 end
271
272 # user factory without associated posts
273 factory :user do
274 name "John Doe"
275
276 # user_with_posts will create post data after the user has been created
277 factory :user_with_posts do
278 # posts_count is declared as an ignored attribute and available in
279 # attributes on the factory, as well as the callback via the evaluator
280 ignore do
281 posts_count 5
282 end
283
284 # the after_create yields two values; the user instance itself and the
285 # evaluator, which stores all values from the factory, including ignored
286 # attributes; `create_list`'s second argument is the number of records
287 # to create and we make sure the user is associated properly to the post
288 after_create do |user, evaluator|
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
289 FactoryGirl.create_list(:post, evaluator.posts_count, user: user)
9c6c252 @joshuaclayton Add tests and documentation for has_many relationships
joshuaclayton authored
290 end
291 end
292 end
293 end
294 ```
295
296 This allows us to do:
297
298 ```ruby
299 FactoryGirl.create(:user).posts.length # 0
300 FactoryGirl.create(:user_with_posts).posts.length # 5
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
301 FactoryGirl.create(:user_with_posts, posts_count: 15).posts.length # 15
9c6c252 @joshuaclayton Add tests and documentation for has_many relationships
joshuaclayton authored
302 ```
303
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
304 Inheritance
305 -----------
306
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
307 You can easily create multiple factories for the same class without repeating common attributes by nesting factories:
308
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
309 ```ruby
310 factory :post do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
311 title "A title"
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
312
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
313 factory :approved_post do
314 approved true
315 end
316 end
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
317
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
318 approved_post = FactoryGirl.create(:approved_post)
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
319 approved_post.title # => "A title"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
320 approved_post.approved # => true
321 ```
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
322
323 You can also assign the parent explicitly:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
324
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
325 ```ruby
326 factory :post do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
327 title "A title"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
328 end
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
329
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
330 factory :approved_post, parent: :post do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
331 approved true
332 end
333 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
334
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
335 As mentioned above, it's good practice to define a basic factory for each class
336 with only the attributes required to create it. Then, create more specific
337 factories that inherit from this basic parent. Factory definitions are still
338 code, so keep them DRY.
90ea1fe @r00k Copy edit GETTING_STARTED. Improve language, examples, and formatting.
r00k authored
339
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
340 Sequences
341 ---------
342
343 Unique values in a specific format (for example, e-mail addresses) can be
344 generated using sequences. Sequences are defined by calling sequence in a
345 definition block, and values in a sequence are generated by calling
8af12f0 @tomstuart Replace Factory.next with FactoryGirl.generate in Getting Started guide
tomstuart authored
346 FactoryGirl.generate:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
347
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
348 ```ruby
349 # Defines a new sequence
350 FactoryGirl.define do
351 sequence :email do |n|
352 "person#{n}@example.com"
353 end
354 end
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
355
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
356 FactoryGirl.generate :email
357 # => "person1@example.com"
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
358
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
359 FactoryGirl.generate :email
360 # => "person2@example.com"
361 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
362
363 Sequences can be used as attributes:
364
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
365 ```ruby
366 factory :user do
367 email
368 end
369 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
370
371 Or in lazy attributes:
372
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
373 ```ruby
374 factory :invite do
375 invitee { FactoryGirl.generate(:email) }
376 end
377 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
378
379 And it's also possible to define an in-line sequence that is only used in
380 a particular factory:
381
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
382 ```ruby
383 factory :user do
384 sequence(:email) {|n| "person#{n}@example.com" }
385 end
386 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
387
71dacea @joshuaclayton Update the sequence documentation
joshuaclayton authored
388 You can also override the initial value:
389
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
390 ```ruby
391 factory :user do
392 sequence(:email, 1000) {|n| "person#{n}@example.com" }
393 end
394 ```
71dacea @joshuaclayton Update the sequence documentation
joshuaclayton authored
395
396 Without a block, the value will increment itself, starting at its initial value:
397
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
398 ```ruby
399 factory :post do
400 sequence(:position)
401 end
402 ```
71dacea @joshuaclayton Update the sequence documentation
joshuaclayton authored
403
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
404 Sequences can also have aliases. The sequence aliases share the same counter:
405
406 ```ruby
407 factory :user do
408 sequence(:email, 1000, :aliases => [:sender, :receiver]) {|n| "person#{n}@example.com" }
409 end
410
411 # will increase value counter for :email which is shared by :sender and :receiver
412 FactoryGirl.next(:sender)
413 ```
414
415 Define aliases and use default value (=1) for the counter
416
417 ```ruby
418 factory :user do
419 sequence(:email, :aliases => [:sender, :receiver]) {|n| "person#{n}@example.com" }
420 end
421 ```
422
423 Setting the value using the :value option:
424
425 ```ruby
426 factory :user do
427 sequence(:email, :value => 'b', :aliases => [:sender, :receiver]) {|n| "person#{n}@example.com" }
428 end
429 ```
430
431 The value just needs to support the `#next` method. Here the next value will be 'b'.
432
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
433 Traits
434 ------
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
435
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
436 Traits allow you to group attributes together and then apply them
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
437 to any factory.
438
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
439 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
440 factory :user, aliases: [:author]
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
441
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
442 factory :story do
443 title "My awesome story"
444 author
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
445
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
446 trait :published do
447 published true
448 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
449
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
450 trait :unpublished do
451 published false
452 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
453
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
454 trait :week_long_publishing do
455 start_at { 1.week.ago }
456 end_at { Time.now }
457 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
458
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
459 trait :month_long_publishing do
460 start_at { 1.month.ago }
461 end_at { Time.now }
462 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
463
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
464 factory :week_long_published_story, traits: [:published, :week_long_publishing]
465 factory :month_long_published_story, traits: [:published, :month_long_publishing]
466 factory :week_long_unpublished_story, traits: [:unpublished, :week_long_publishing]
467 factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
468 end
469 ```
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
470
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
471 Traits can be used as attributes:
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
472
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
473 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
474 factory :week_long_published_story_with_title, parent: :story do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
475 published
476 week_long_publishing
477 title { "Publishing that was started at {start_at}" }
478 end
479 ```
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
480
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
481 Traits that define the same attributes won't raise AttributeDefinitionErrors;
482 the trait that defines the attribute latest gets precedence.
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
483
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
484 ```ruby
485 factory :user do
486 name "Friendly User"
487 login { name }
488
489 trait :male do
490 name "John Doe"
491 gender "Male"
492 login { "#{name} (M)" }
493 end
494
495 trait :female do
496 name "Jane Doe"
497 gender "Female"
498 login { "#{name} (F)" }
499 end
500
501 trait :admin do
502 admin true
503 login { "admin-#{name}" }
504 end
505
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
506 factory :male_admin, traits: [:male, :admin] # login will be "admin-John Doe"
507 factory :female_admin, traits: [:admin, :female] # login will be "Jane Doe (F)"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
508 end
509 ```
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
510
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
511 You can also override individual attributes granted by a trait in subclasses.
512
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
513 ```ruby
514 factory :user do
515 name "Friendly User"
516 login { name }
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
517
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
518 trait :male do
519 name "John Doe"
520 gender "Male"
521 login { "#{name} (M)" }
522 end
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
523
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
524 factory :brandon do
525 male
526 name "Brandon"
527 end
528 end
529 ```
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
530
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
531 Traits can also be passed in as a list of symbols when you construct an instance from FactoryGirl.
532
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
533 ```ruby
534 factory :user do
535 name "Friendly User"
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
536
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
537 trait :male do
538 name "John Doe"
539 gender "Male"
540 end
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
541
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
542 trait :admin do
543 admin true
544 end
545 end
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
546
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
547 # creates an admin user with gender "Male" and name "Jon Snow"
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
548 FactoryGirl.create(:user, :admin, :male, name: "Jon Snow")
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
549 ```
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
550
551 This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
552
13129b0 @weppos Document build_list and create_list with runtime traits.
weppos authored
553 `create_list` and `build_list` methods are supported as well. Just remember to pass
554 the number of instances to create/build as second parameter, as documented in the
555 "Building or Creating Multiple Records" section of this file.
556
557 ```ruby
558 factory :user do
559 name "Friendly User"
560
561 trait :admin do
562 admin true
563 end
564 end
565
566 # creates 3 admin users with gender "Male" and name "Jon Snow"
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
567 FactoryGirl.create_list(:user, 3, :admin, :male, name: "Jon Snow")
13129b0 @weppos Document build_list and create_list with runtime traits.
weppos authored
568 ```
569
570
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
571 Callbacks
572 ---------
573
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
574 factory\_girl makes available three callbacks for injecting some code:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
575
576 * after_build - called after a factory is built (via FactoryGirl.build)
577 * after_create - called after a factory is saved (via FactoryGirl.create)
08018f6 @carlosantoniodasilva Change getting started doc to remove old "FactoryGirl.stub" method
carlosantoniodasilva authored
578 * after_stub - called after a factory is stubbed (via FactoryGirl.build_stubbed)
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
579
580 Examples:
581
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
582 ```ruby
583 # Define a factory that calls the generate_hashed_password method after it is built
584 factory :user do
585 after_build { |user| generate_hashed_password(user) }
586 end
587 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
588
4d83729 @joshuaclayton Documentation fixes
joshuaclayton authored
589 Note that you'll have an instance of the user in the block. This can be useful.
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
590
591 You can also define multiple types of callbacks on the same factory:
592
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
593 ```ruby
594 factory :user do
595 after_build { |user| do_something_to(user) }
596 after_create { |user| do_something_else_to(user) }
597 end
598 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
599
600 Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
601
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
602 ```ruby
603 factory :user do
604 after_create { this_runs_first }
605 after_create { then_this }
606 end
607 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
608
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
609 Calling FactoryGirl.create will invoke both after\_build and after\_create callbacks.
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
610
611 Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
612
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
613 Modifying factories
614 -------------------
615
616 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
617 modify that factory instead of creating a child factory and adding attributes there.
618
619 If a gem were to give you a User factory:
620
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
621 ```ruby
622 FactoryGirl.define do
623 factory :user do
624 full_name "John Doe"
625 sequence(:username) {|n| "user#{n}" }
626 password "password"
627 end
628 end
629 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
630
631 Instead of creating a child factory that added additional attributes:
632
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
633 ```ruby
634 FactoryGirl.define do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
635 factory :application_user, parent: :user do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
636 full_name { Faker::Name.name }
637 date_of_birth { 21.years.ago }
638 gender "Female"
639 health 90
640 end
641 end
642 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
643
644 You could modify that factory instead.
645
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
646 ```ruby
647 FactoryGirl.modify do
648 factory :user do
649 full_name { Faker::Name.name }
650 date_of_birth { 21.years.ago }
651 gender "Female"
652 health 90
653 end
654 end
655 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
656
657 When modifying a factory, you can change any of the attributes you want (aside from callbacks).
658
659 `FactoryGirl.modify` must be called outside of a `FactoryGirl.define` block as it operates on factories differently.
660
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
661 A caveat: you can only modify factories (not sequences or traits) and callbacks *still compound as they normally would*. So, if
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
662 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.
663
dd7aa22 @pythonandchips Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
664 Building or Creating Multiple Records
665 -------------------------------------
666
667 Sometimes, you'll want to create or build multiple instances of a factory at once.
668
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
669 ```ruby
670 built_users = FactoryGirl.build_list(:user, 25)
671 created_users = FactoryGirl.create_list(:user, 25)
672 ```
dd7aa22 @pythonandchips Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
673
674 These methods will build or create a specific amount of factories and return them as an array.
675 To set the attributes for each of the factories, you can pass in a hash as you normally would.
676
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
677 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
678 twenty_year_olds = FactoryGirl.build_list(:user, 25, date_of_birth: 20.years.ago)
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
679 ```
dd7aa22 @pythonandchips Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
680
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
681 Custom Construction
682 -------------------
683
ea89aad @jferris Update README with more to_initialize info
jferris authored
684 If you want to use factory_girl to construct an object where some attributes
685 are passed to `initialize` or if you want to do something other than simply
686 calling `new` on your build class, you can override the default behavior by
687 defining `to_initialize` on your factory. Example:
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
688
689 ```ruby
690 # user.rb
691 class User
692 attr_accessor :name, :email
693
694 def initialize(name)
695 @name = name
696 end
697 end
698
699 # factories.rb
700 sequence(:name) {|n| "person#{n}@example.com" }
701
702 factory :user do
703 ignore do
704 name { Faker::Name.name }
705 end
706
707 email
708 initialize_with { User.new(name) }
709 end
710
711 FactoryGirl.build(:user).name # Bob Hope
712 ```
713
714 Notice that I ignored the `name` attribute. If you don't want attributes
715 reassigned after your object has been instantiated, you'll want to `ignore` them.
716
ea89aad @jferris Update README with more to_initialize info
jferris authored
717 Although factory_girl is written to work with ActiveRecord out of the box, it
718 can also work with any Ruby class. For maximum compatibiltiy with ActiveRecord,
719 the default initializer builds all instances by calling new on your build class
720 without any arguments. It then calls attribute writer methods to assign all the
721 attribute values. While that works fine for ActiveRecord, it actually doesn't
722 work for almost any other Ruby class.
723
724 You can override the initializer in order to:
725
726 * Build non-ActiveRecord objects that require arguments to `initialize`
727 * Use a method other than `new` to instantiate the instance
728 * Do crazy things like decorate the instance after it's built
729
49a47fa @gabebw Edited GETTING_STARTED.md via GitHub
gabebw authored
730 Cucumber Integration
731 --------------------
732
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
733 factory\_girl ships with step definitions that make calling factories from Cucumber easier. To use them, add the following to features/support/env.rb:
49a47fa @gabebw Edited GETTING_STARTED.md via GitHub
gabebw authored
734
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
735 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
736 require "factory_girl/step_definitions"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
737 ```
49a47fa @gabebw Edited GETTING_STARTED.md via GitHub
gabebw authored
738
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
739 Alternate Syntaxes
740 ------------------
741
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
742 Users' tastes for syntax vary dramatically, but most users are looking for a
743 common feature set. Because of this factory\_girl supports "syntax layers" which
744 provide alternate interfaces. See Factory::Syntax for information about the
745 various layers available. For example, the Machinist-style syntax is popular:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
746
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
747 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
748 require "factory_girl/syntax/blueprint"
749 require "factory_girl/syntax/make"
750 require "factory_girl/syntax/sham"
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
751
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
752 Sham.email {|n| "#{n}@example.com" }
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
753
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
754 User.blueprint do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
755 name { "Billy Bob" }
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
756 email { Sham.email }
757 end
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
758
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
759 User.make(name: "Johnny")
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
760 ```
Something went wrong with that request. Please try again.