Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 860 lines (653 sloc) 21.916 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
3768d15 Add documentation to using syntax methods inside dynamic attributes
Ben Zhang and Josh Clayton authored
133 In addition to running other methods dynamically, you can use FactoryGirl's
134 syntax methods (like `build`, `create`, and `generate`) within dynamic
135 attributes without having to prefix the call with `FactoryGirl.`. This allows
136 you to do:
137
138 ```ruby
139 sequence(:random_string) {|n| LoremIpsum.generate }
140
141 factory :post do
142 title { generate(:random_string) } # instead of FactoryGirl.generate(:random_string)
143 end
144
145 factory :comment do
146 post
147 body { generate(:random_string) } # instead of FactoryGirl.generate(:random_string)
148 end
149 ```
150
9e1024b @joshuaclayton More docs
joshuaclayton authored
151 Aliases
152 -------
153
154 Aliases allow you to use named associations more easily.
155
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
156 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
157 factory :user, aliases: [:author, :commenter] do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
158 first_name "John"
159 last_name "Doe"
160 date_of_birth { 18.years.ago }
161 end
162
163 factory :post do
164 author
165 # instead of
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
166 # association :author, factory: :user
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
167 title "How to read a book effectively"
168 body "There are five steps involved."
169 end
170
171 factory :comment do
172 commenter
173 # instead of
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
174 # association :commenter, factory: :user
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
175 body "Great article!"
176 end
177 ```
9e1024b @joshuaclayton More docs
joshuaclayton authored
178
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
179 Dependent Attributes
180 --------------------
181
b79a525 @joshuaclayton Proxy => Strategy
joshuaclayton authored
182 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
183
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
184 ```ruby
185 factory :user do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
186 first_name "Joe"
187 last_name "Blow"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
188 email { "#{first_name}.#{last_name}@example.com".downcase }
189 end
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
190
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
191 FactoryGirl.create(:user, last_name: "Doe").email
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
192 # => "joe.doe@example.com"
193 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
194
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
195 Transient Attributes
196 --------------------
197
198 There may be times where your code can be DRYed up by passing in transient attributes to factories.
199
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
200 ```ruby
201 factory :user do
202 ignore do
203 rockstar true
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
204 upcased false
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
205 end
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
206
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
207 name { "John Doe#{" - Rockstar" if rockstar}" }
208 email { "#{name.downcase}@example.com" }
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
209
b79a525 @joshuaclayton Proxy => Strategy
joshuaclayton authored
210 after_create do |user, evaluator|
211 user.name.upcase! if evaluator.upcased
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
212 end
213 end
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
214
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
215 FactoryGirl.create(:user, upcased: true).name
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
216 #=> "JOHN DOE - ROCKSTAR"
217 ```
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
218
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
219 Static and dynamic attributes can be ignored. Ignored attributes will be ignored
220 within attributes\_for and won't be set on the model, even if the attribute
221 exists or you attempt to override it.
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
222
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
223 Within Factory Girl's dynamic attributes, you can access ignored attributes as
b79a525 @joshuaclayton Proxy => Strategy
joshuaclayton authored
224 you would expect. If you need to access the evaluator in a Factory Girl callback,
225 you'll need to declare a second block argument (for the evaluator) and access
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
226 ignored attributes from there.
c87429b @joshuaclayton Add transient variables
joshuaclayton authored
227
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
228 Associations
229 ------------
230
25affc7 @betelgeuse Typo fix possbile to possible
betelgeuse authored
231 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
232
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
233 ```ruby
234 factory :post do
235 # ...
236 author
237 end
238 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
239
240 You can also specify a different factory or override attributes:
241
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
242 ```ruby
243 factory :post do
244 # ...
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
245 association :author, factory: :user, last_name: "Writely"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
246 end
247 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
248
249 The behavior of the association method varies depending on the build strategy used for the parent object.
250
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
251 ```ruby
252 # Builds and saves a User and a Post
253 post = FactoryGirl.create(:post)
254 post.new_record? # => false
255 post.author.new_record? # => false
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
256
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
257 # Builds and saves a User, and then builds but does not save a Post
258 post = FactoryGirl.build(:post)
259 post.new_record? # => true
260 post.author.new_record? # => false
261 ```
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
262
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
263 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
264
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
265 ```ruby
266 factory :post do
267 # ...
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
268 association :author, factory: :user, strategy: :build
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
269 end
9037481 Now able to specify :method => :build in a factory's association.
Jim Kingdon authored
270
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
271 # Builds a User, and then builds a Post, but does not save either
272 post = FactoryGirl.build(:post)
273 post.new_record? # => true
274 post.author.new_record? # => true
275 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
276
9c6c252 @joshuaclayton Add tests and documentation for has_many relationships
joshuaclayton authored
277 Generating data for a `has_many` relationship is a bit more involved,
278 depending on the amount of flexibility desired, but here's a surefire example
279 of generating associated data.
280
281 ```ruby
282 FactoryGirl.define do
283
284 # post factory with a `belongs_to` association for the user
285 factory :post do
286 title "Through the Looking Glass"
287 user
288 end
289
290 # user factory without associated posts
291 factory :user do
292 name "John Doe"
293
294 # user_with_posts will create post data after the user has been created
295 factory :user_with_posts do
296 # posts_count is declared as an ignored attribute and available in
297 # attributes on the factory, as well as the callback via the evaluator
298 ignore do
299 posts_count 5
300 end
301
302 # the after_create yields two values; the user instance itself and the
303 # evaluator, which stores all values from the factory, including ignored
304 # attributes; `create_list`'s second argument is the number of records
305 # to create and we make sure the user is associated properly to the post
306 after_create do |user, evaluator|
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
307 FactoryGirl.create_list(:post, evaluator.posts_count, user: user)
9c6c252 @joshuaclayton Add tests and documentation for has_many relationships
joshuaclayton authored
308 end
309 end
310 end
311 end
312 ```
313
314 This allows us to do:
315
316 ```ruby
317 FactoryGirl.create(:user).posts.length # 0
318 FactoryGirl.create(:user_with_posts).posts.length # 5
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
319 FactoryGirl.create(:user_with_posts, posts_count: 15).posts.length # 15
9c6c252 @joshuaclayton Add tests and documentation for has_many relationships
joshuaclayton authored
320 ```
321
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
322 Inheritance
323 -----------
324
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
325 You can easily create multiple factories for the same class without repeating common attributes by nesting factories:
326
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
327 ```ruby
328 factory :post do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
329 title "A title"
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
330
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
331 factory :approved_post do
332 approved true
333 end
334 end
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
335
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
336 approved_post = FactoryGirl.create(:approved_post)
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
337 approved_post.title # => "A title"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
338 approved_post.approved # => true
339 ```
0c06997 @joshuaclayton Allow child factories to be defined by nesting
joshuaclayton authored
340
341 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
342
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
343 ```ruby
344 factory :post do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
345 title "A title"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
346 end
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
347
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
348 factory :approved_post, parent: :post do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
349 approved true
350 end
351 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
352
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
353 As mentioned above, it's good practice to define a basic factory for each class
354 with only the attributes required to create it. Then, create more specific
355 factories that inherit from this basic parent. Factory definitions are still
356 code, so keep them DRY.
90ea1fe @r00k Copy edit GETTING_STARTED. Improve language, examples, and formatting.
r00k authored
357
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
358 Sequences
359 ---------
360
361 Unique values in a specific format (for example, e-mail addresses) can be
362 generated using sequences. Sequences are defined by calling sequence in a
363 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
364 FactoryGirl.generate:
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
365
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
366 ```ruby
367 # Defines a new sequence
368 FactoryGirl.define do
369 sequence :email do |n|
370 "person#{n}@example.com"
371 end
372 end
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
373
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
374 FactoryGirl.generate :email
375 # => "person1@example.com"
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
376
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
377 FactoryGirl.generate :email
378 # => "person2@example.com"
379 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
380
381 Sequences can be used as attributes:
382
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
383 ```ruby
384 factory :user do
385 email
386 end
387 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
388
389 Or in lazy attributes:
390
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
391 ```ruby
392 factory :invite do
3768d15 Add documentation to using syntax methods inside dynamic attributes
Ben Zhang and Josh Clayton authored
393 invitee { generate(:email) }
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
394 end
395 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
396
397 And it's also possible to define an in-line sequence that is only used in
398 a particular factory:
399
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
400 ```ruby
401 factory :user do
402 sequence(:email) {|n| "person#{n}@example.com" }
403 end
404 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
405
71dacea @joshuaclayton Update the sequence documentation
joshuaclayton authored
406 You can also override the initial value:
407
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
408 ```ruby
409 factory :user do
410 sequence(:email, 1000) {|n| "person#{n}@example.com" }
411 end
412 ```
71dacea @joshuaclayton Update the sequence documentation
joshuaclayton authored
413
414 Without a block, the value will increment itself, starting at its initial value:
415
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
416 ```ruby
417 factory :post do
418 sequence(:position)
419 end
420 ```
71dacea @joshuaclayton Update the sequence documentation
joshuaclayton authored
421
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
422 Sequences can also have aliases. The sequence aliases share the same counter:
423
424 ```ruby
425 factory :user do
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
426 sequence(:email, 1000, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
427 end
428
429 # will increase value counter for :email which is shared by :sender and :receiver
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
430 FactoryGirl.next(:sender)
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
431 ```
432
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
433 Define aliases and use default value (1) for the counter
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
434
435 ```ruby
436 factory :user do
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
437 sequence(:email, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
438 end
439 ```
440
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
441 Setting the value:
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
442
443 ```ruby
444 factory :user do
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
445 sequence(:email, 'a', aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
446 end
447 ```
448
4ef98ff @joshuaclayton Clean up
joshuaclayton authored
449 The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
f013335 @kristianmandrup updated Getting Started with docu on new aliased sequence functionality
kristianmandrup authored
450
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
451 Traits
452 ------
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
453
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
454 Traits allow you to group attributes together and then apply them
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
455 to any factory.
456
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
457 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
458 factory :user, aliases: [:author]
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
459
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
460 factory :story do
461 title "My awesome story"
462 author
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
463
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
464 trait :published do
465 published true
466 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
467
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
468 trait :unpublished do
469 published false
470 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
471
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
472 trait :week_long_publishing do
473 start_at { 1.week.ago }
474 end_at { Time.now }
475 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
476
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
477 trait :month_long_publishing do
478 start_at { 1.month.ago }
479 end_at { Time.now }
480 end
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
481
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
482 factory :week_long_published_story, traits: [:published, :week_long_publishing]
483 factory :month_long_published_story, traits: [:published, :month_long_publishing]
484 factory :week_long_unpublished_story, traits: [:unpublished, :week_long_publishing]
485 factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
486 end
487 ```
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
488
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
489 Traits can be used as attributes:
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
490
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
491 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
492 factory :week_long_published_story_with_title, parent: :story do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
493 published
494 week_long_publishing
495 title { "Publishing that was started at {start_at}" }
496 end
497 ```
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
498
1c74d9d @joshuaclayton Rename attribute groups to traits
joshuaclayton authored
499 Traits that define the same attributes won't raise AttributeDefinitionErrors;
500 the trait that defines the attribute latest gets precedence.
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
501
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
502 ```ruby
503 factory :user do
504 name "Friendly User"
505 login { name }
506
507 trait :male do
508 name "John Doe"
509 gender "Male"
510 login { "#{name} (M)" }
511 end
512
513 trait :female do
514 name "Jane Doe"
515 gender "Female"
516 login { "#{name} (F)" }
517 end
518
519 trait :admin do
520 admin true
521 login { "admin-#{name}" }
522 end
523
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
524 factory :male_admin, traits: [:male, :admin] # login will be "admin-John Doe"
525 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
526 end
527 ```
86125a4 @joshuaclayton Document attribute groups
joshuaclayton authored
528
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
529 You can also override individual attributes granted by a trait in subclasses.
530
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
531 ```ruby
532 factory :user do
533 name "Friendly User"
534 login { name }
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
535
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
536 trait :male do
537 name "John Doe"
538 gender "Male"
539 login { "#{name} (M)" }
540 end
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
541
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
542 factory :brandon do
543 male
544 name "Brandon"
545 end
546 end
547 ```
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
548
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
549 Traits can also be passed in as a list of symbols when you construct an instance from FactoryGirl.
550
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
551 ```ruby
552 factory :user do
553 name "Friendly User"
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
554
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
555 trait :male do
556 name "John Doe"
557 gender "Male"
558 end
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
559
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
560 trait :admin do
561 admin true
562 end
563 end
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
564
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
565 # creates an admin user with gender "Male" and name "Jon Snow"
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
566 FactoryGirl.create(:user, :admin, :male, name: "Jon Snow")
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
567 ```
442ba18 @joshuaclayton Traits can be added to factories when the factory creates an instance
joshuaclayton authored
568
569 This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
570
13129b0 @weppos Document build_list and create_list with runtime traits.
weppos authored
571 `create_list` and `build_list` methods are supported as well. Just remember to pass
572 the number of instances to create/build as second parameter, as documented in the
573 "Building or Creating Multiple Records" section of this file.
574
575 ```ruby
576 factory :user do
577 name "Friendly User"
578
579 trait :admin do
580 admin true
581 end
582 end
583
584 # creates 3 admin users with gender "Male" and name "Jon Snow"
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
585 FactoryGirl.create_list(:user, 3, :admin, :male, name: "Jon Snow")
13129b0 @weppos Document build_list and create_list with runtime traits.
weppos authored
586 ```
587
588
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
589 Callbacks
590 ---------
591
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
592 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
593
594 * after_build - called after a factory is built (via FactoryGirl.build)
595 * 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
596 * 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
597
598 Examples:
599
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
600 ```ruby
601 # Define a factory that calls the generate_hashed_password method after it is built
602 factory :user do
603 after_build { |user| generate_hashed_password(user) }
604 end
605 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
606
4d83729 @joshuaclayton Documentation fixes
joshuaclayton authored
607 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
608
609 You can also define multiple types of callbacks on the same factory:
610
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
611 ```ruby
612 factory :user do
613 after_build { |user| do_something_to(user) }
614 after_create { |user| do_something_else_to(user) }
615 end
616 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
617
618 Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
619
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
620 ```ruby
621 factory :user do
622 after_create { this_runs_first }
623 after_create { then_this }
624 end
625 ```
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
626
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
627 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
628
629 Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
630
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
631 Modifying factories
632 -------------------
633
634 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
635 modify that factory instead of creating a child factory and adding attributes there.
636
637 If a gem were to give you a User factory:
638
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
639 ```ruby
640 FactoryGirl.define do
641 factory :user do
642 full_name "John Doe"
643 sequence(:username) {|n| "user#{n}" }
644 password "password"
645 end
646 end
647 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
648
649 Instead of creating a child factory that added additional attributes:
650
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
651 ```ruby
652 FactoryGirl.define do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
653 factory :application_user, parent: :user do
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
654 full_name { Faker::Name.name }
655 date_of_birth { 21.years.ago }
656 gender "Female"
657 health 90
658 end
659 end
660 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
661
662 You could modify that factory instead.
663
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
664 ```ruby
665 FactoryGirl.modify do
666 factory :user do
667 full_name { Faker::Name.name }
668 date_of_birth { 21.years.ago }
669 gender "Female"
670 health 90
671 end
672 end
673 ```
14b8245 Allow factories to be modified after they've been defined.
Stephan Eckardt and Josh Clayton authored
674
675 When modifying a factory, you can change any of the attributes you want (aside from callbacks).
676
677 `FactoryGirl.modify` must be called outside of a `FactoryGirl.define` block as it operates on factories differently.
678
a154e64 Introduce declarations
Joe Ferris and Josh Clayton authored
679 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
680 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.
681
dd7aa22 @pythonandchips Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
682 Building or Creating Multiple Records
683 -------------------------------------
684
685 Sometimes, you'll want to create or build multiple instances of a factory at once.
686
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
687 ```ruby
688 built_users = FactoryGirl.build_list(:user, 25)
689 created_users = FactoryGirl.create_list(:user, 25)
690 ```
dd7aa22 @pythonandchips Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
691
692 These methods will build or create a specific amount of factories and return them as an array.
693 To set the attributes for each of the factories, you can pass in a hash as you normally would.
694
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
695 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
696 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
697 ```
dd7aa22 @pythonandchips Added create|build_list for easy generation of multiple factories at onc...
pythonandchips authored
698
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
699 Custom Construction
700 -------------------
701
ea89aad @jferris Update README with more to_initialize info
jferris authored
702 If you want to use factory_girl to construct an object where some attributes
703 are passed to `initialize` or if you want to do something other than simply
704 calling `new` on your build class, you can override the default behavior by
4682ab0 @mark-rushakoff fix typo in GETTING_STARTED
mark-rushakoff authored
705 defining `initialize_with` on your factory. Example:
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
706
707 ```ruby
708 # user.rb
709 class User
710 attr_accessor :name, :email
711
712 def initialize(name)
713 @name = name
714 end
715 end
716
717 # factories.rb
718 sequence(:name) {|n| "person#{n}@example.com" }
719
720 factory :user do
721 ignore do
722 name { Faker::Name.name }
723 end
724
725 email
9907826 @joshuaclayton Base class is implied when calling .new within initialize_with
joshuaclayton authored
726 initialize_with { new(name) }
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
727 end
728
729 FactoryGirl.build(:user).name # Bob Hope
730 ```
731
732 Notice that I ignored the `name` attribute. If you don't want attributes
733 reassigned after your object has been instantiated, you'll want to `ignore` them.
734
ea89aad @jferris Update README with more to_initialize info
jferris authored
735 Although factory_girl is written to work with ActiveRecord out of the box, it
736 can also work with any Ruby class. For maximum compatibiltiy with ActiveRecord,
737 the default initializer builds all instances by calling new on your build class
738 without any arguments. It then calls attribute writer methods to assign all the
739 attribute values. While that works fine for ActiveRecord, it actually doesn't
740 work for almost any other Ruby class.
741
742 You can override the initializer in order to:
743
744 * Build non-ActiveRecord objects that require arguments to `initialize`
745 * Use a method other than `new` to instantiate the instance
746 * Do crazy things like decorate the instance after it's built
747
9907826 @joshuaclayton Base class is implied when calling .new within initialize_with
joshuaclayton authored
748 When using `initialize_with`, you don't have to declare the class itself when
749 calling `new`; however, any other class methods you want to call will have to
750 be called on the class explicitly.
751
752 For example:
753
754 ```ruby
755 factory :user do
756 ignore do
757 name { Faker::Name.name }
758 end
759
760 initialize_with { User.build_with_name(name) }
761 end
762 ```
763
c8c1a80 @joshuaclayton Add ability to register custom strategies
joshuaclayton authored
764 Custom Strategies
765 -----------------
766
767 There are times where you may want to extend behavior of factory\_girl by
768 adding a custom build strategy.
769
770 Strategies define two methods: `association` and `result`. `association`
771 receives a `FactoryGirl::FactoryRunner` instance, upon which you can call
772 `run`, overriding the strategy if you want. The second method, `result`,
773 receives a `FactoryGirl::Evaluation` instance. It provides a way to trigger
774 callbacks (with `notify`), `object` or `hash` (to get the result instance or a
775 hash based on the attributes defined in the factory), and `create`, which
776 executes the `to_create` callback defined on the factory.
777
778 To understand how factory\_girl uses strategies internally, it's probably
779 easiest to just view the source for each of the four default strategies.
780
781 Inheritance can occasionally be useful; here's an example of inheriting from
782 `FactoryGirl::Strategy::Create` to build a JSON representation of your model.
783
784 ```ruby
785 class JsonStrategy < FactoryGirl::Strategy::Create
786 def result(evaluation)
787 super.to_json
788 end
789 end
790 ```
791
792 For factory\_girl to recognize the new strategy, you can register it:
793
794 ```ruby
795 FactoryGirl.register_strategy(:json, JsonStrategy)
796 ```
797
798 This allows you to call
799
800 ```ruby
801 FactoryGirl.json(:user)
802 ```
803
804 Finally, you can override factory\_girl's own strategies if you'd like by
805 registering a new object in place of the strategies.
806
351b04d @joshuaclayton Allow a user to skip the default create execution
joshuaclayton authored
807 Custom Methods to Persist Objects
808 ------------------------------
809
810 By default, creating a record will call `save!` on the instance; since this
811 may not always be ideal, you can override that behavior by defining
812 `to_create` on the factory:
813
814 ```ruby
815 factory :different_orm_model do
816 to_create {|instance| instance.persist! }
817 end
818 ```
819
820 To disable the persistence method altogether on create, you can `skip_create`
821 for that factory:
822
823 ```ruby
824 factory :user_without_database do
825 skip_create
826 end
827 ```
828
49a47fa @gabebw Edited GETTING_STARTED.md via GitHub
gabebw authored
829 Cucumber Integration
830 --------------------
831
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
832 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
833
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
834 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
835 require "factory_girl/step_definitions"
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
836 ```
49a47fa @gabebw Edited GETTING_STARTED.md via GitHub
gabebw authored
837
3acd41d @jferris Extract examples out to a different file so that the readme people see o...
jferris authored
838 Alternate Syntaxes
839 ------------------
840
67fc3bc @gabebw Whitespace, textwidth, and escaping underscores.
gabebw authored
841 Users' tastes for syntax vary dramatically, but most users are looking for a
842 common feature set. Because of this factory\_girl supports "syntax layers" which
843 provide alternate interfaces. See Factory::Syntax for information about the
844 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
845
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
846 ```ruby
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
847 require "factory_girl/syntax/blueprint"
848 require "factory_girl/syntax/make"
849 require "factory_girl/syntax/sham"
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
850
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
851 Sham.email {|n| "#{n}@example.com" }
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
852
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
853 User.blueprint do
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
854 name { "Billy Bob" }
1e82889 @dasch Make the examples use Ruby syntax highlighting on GitHub.
dasch authored
855 email { Sham.email }
856 end
cbd42ed @joshuaclayton Whitespace
joshuaclayton authored
857
055c976 @joshuaclayton Update getting started style
joshuaclayton authored
858 User.make(name: "Johnny")
5780364 @joshuaclayton Implement initialize_with to allow overriding object instantiation
joshuaclayton authored
859 ```
Something went wrong with that request. Please try again.