factory_girl 4.3.0 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/GETTING_STARTED.md +143 -137
- data/Gemfile.lock +1 -1
- data/LICENSE +1 -1
- data/NEWS +14 -0
- data/README.md +4 -4
- data/gemfiles/3.1.gemfile.lock +1 -1
- data/gemfiles/3.2.gemfile.lock +1 -1
- data/gemfiles/4.0.gemfile.lock +1 -1
- data/lib/factory_girl.rb +20 -0
- data/lib/factory_girl/attribute_assigner.rb +1 -1
- data/lib/factory_girl/attribute_list.rb +1 -1
- data/lib/factory_girl/callbacks_observer.rb +1 -1
- data/lib/factory_girl/configuration.rb +1 -1
- data/lib/factory_girl/declaration_list.rb +2 -2
- data/lib/factory_girl/definition.rb +7 -7
- data/lib/factory_girl/errors.rb +3 -0
- data/lib/factory_girl/factory.rb +2 -2
- data/lib/factory_girl/find_definitions.rb +1 -1
- data/lib/factory_girl/version.rb +1 -1
- data/spec/acceptance/callbacks_spec.rb +4 -4
- data/spec/acceptance/global_to_create_spec.rb +3 -3
- data/spec/acceptance/initialize_with_spec.rb +2 -2
- data/spec/acceptance/keyed_by_class_spec.rb +1 -1
- data/spec/acceptance/lint_spec.rb +55 -0
- data/spec/acceptance/modify_factories_spec.rb +1 -1
- data/spec/acceptance/nested_attributes_spec.rb +1 -1
- data/spec/acceptance/parent_spec.rb +1 -1
- data/spec/acceptance/sequence_context_spec.rb +4 -4
- data/spec/acceptance/sequence_spec.rb +2 -2
- data/spec/acceptance/syntax_methods_within_dynamic_attributes_spec.rb +2 -2
- data/spec/acceptance/traits_spec.rb +12 -12
- data/spec/acceptance/transient_attributes_spec.rb +1 -1
- data/spec/factory_girl/attribute/dynamic_spec.rb +1 -1
- data/spec/factory_girl/definition_proxy_spec.rb +1 -1
- data/spec/factory_girl/definition_spec.rb +7 -1
- data/spec/factory_girl/sequence_spec.rb +4 -4
- data/spec/support/matchers/trait.rb +3 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b01f71363317939e019ac18363d51ce2b2caa9f0
|
|
4
|
+
data.tar.gz: cb128a3c6ade6aa7d1222fb4f86e6a81504dbc8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3468641fa299f92b03cf869d2b3bfe9f75dce4de90f94b8cc2ebc86e9240177f8e514bfcf5ad44f99e17042112f1eb587dd2256df3c8606e8791d6580a818a2b
|
|
7
|
+
data.tar.gz: ffc2c949b1e3e344ad56a0a6609203d33c2464c20888a1aca53ca95530dcab8d74dc4d712a3b54fee55d94682422081782b8638c47a62e8f4c18a9238c43d999
|
data/.travis.yml
CHANGED
data/GETTING_STARTED.md
CHANGED
|
@@ -16,7 +16,7 @@ If you're *not* using Rails, you'll just have to change the required version of
|
|
|
16
16
|
gem "factory_girl", "~> 4.0"
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
JRuby users:
|
|
19
|
+
JRuby users: factory_girl works with JRuby starting with 1.6.7.2 (latest stable, as per July 2012).
|
|
20
20
|
JRuby has to be used in 1.9 mode, for that, use JRUBY_OPTS environment variable:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
@@ -25,40 +25,70 @@ export JRUBY_OPTS=--1.9
|
|
|
25
25
|
|
|
26
26
|
Once your Gemfile is updated, you'll want to update your bundle.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
If you're not using Bundler, be sure to have the gem installed and call:
|
|
28
|
+
Configure your test suite
|
|
29
|
+
-------------------------
|
|
32
30
|
|
|
33
31
|
```ruby
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
# rspec
|
|
33
|
+
RSpec.configure do |config|
|
|
34
|
+
config.include FactoryGirl::Syntax::Methods
|
|
35
|
+
end
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
# Test::Unit
|
|
38
|
+
class Test::Unit::TestCase
|
|
39
|
+
include FactoryGirl::Syntax::Methods
|
|
40
|
+
end
|
|
39
41
|
|
|
40
|
-
|
|
41
|
-
FactoryGirl
|
|
42
|
+
# Cucumber
|
|
43
|
+
World(FactoryGirl::Syntax::Methods)
|
|
44
|
+
|
|
45
|
+
# Spinach
|
|
46
|
+
class Spinach::FeatureSteps
|
|
47
|
+
include FactoryGirl::Syntax::Methods
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# MiniTest
|
|
51
|
+
class MiniTest::Unit::TestCase
|
|
52
|
+
include FactoryGirl::Syntax::Methods
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# MiniTest::Spec
|
|
56
|
+
class MiniTest::Spec
|
|
57
|
+
include FactoryGirl::Syntax::Methods
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# minitest-rails
|
|
61
|
+
class MiniTest::Rails::ActiveSupport::TestCase
|
|
62
|
+
include FactoryGirl::Syntax::Methods
|
|
63
|
+
end
|
|
42
64
|
```
|
|
43
65
|
|
|
44
|
-
If you
|
|
45
|
-
|
|
66
|
+
If you do not include `FactoryGirl::Syntax::Methods` in your test suite, then all factory_girl methods will need to be prefaced with `FactoryGirl`.
|
|
67
|
+
|
|
68
|
+
Linting Factories
|
|
69
|
+
-----------------
|
|
70
|
+
|
|
71
|
+
factory_girl allows for linting known factories:
|
|
46
72
|
|
|
47
73
|
```ruby
|
|
48
|
-
FactoryGirl.
|
|
49
|
-
FactoryGirl.find_definitions
|
|
74
|
+
FactoryGirl.lint
|
|
50
75
|
```
|
|
51
76
|
|
|
52
|
-
|
|
53
|
-
|
|
77
|
+
`FactoryGirl.lint` builds each factory and subsequently calls `#valid?` on it
|
|
78
|
+
(if `#valid?` is defined); if any calls to `#valid?` return `false`,
|
|
79
|
+
`FactoryGirl::InvalidFactoryError` is raised with a list of the offending
|
|
80
|
+
factories. Recommended usage of `FactoryGirl.lint` is to invoke this once
|
|
81
|
+
before the test suite is run.
|
|
82
|
+
|
|
83
|
+
With RSpec:
|
|
54
84
|
|
|
55
85
|
```ruby
|
|
56
|
-
|
|
86
|
+
# spec/support/factory_girl.rb
|
|
87
|
+
RSpec.configure do |config|
|
|
88
|
+
# additional factory_girl configuration
|
|
57
89
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
name 'John Doe'
|
|
61
|
-
date_of_birth { 21.years.ago }
|
|
90
|
+
config.before(:suite) do
|
|
91
|
+
FactoryGirl.lint
|
|
62
92
|
end
|
|
63
93
|
end
|
|
64
94
|
```
|
|
@@ -105,19 +135,19 @@ factory\_girl supports several different build strategies: build, create, attrib
|
|
|
105
135
|
|
|
106
136
|
```ruby
|
|
107
137
|
# Returns a User instance that's not saved
|
|
108
|
-
user =
|
|
138
|
+
user = build(:user)
|
|
109
139
|
|
|
110
140
|
# Returns a saved User instance
|
|
111
|
-
user =
|
|
141
|
+
user = create(:user)
|
|
112
142
|
|
|
113
143
|
# Returns a hash of attributes that can be used to build a User instance
|
|
114
|
-
attrs =
|
|
144
|
+
attrs = attributes_for(:user)
|
|
115
145
|
|
|
116
146
|
# Returns an object with all defined attributes stubbed out
|
|
117
|
-
stub =
|
|
147
|
+
stub = build_stubbed(:user)
|
|
118
148
|
|
|
119
149
|
# Passing a block to any of the methods above will yield the return object
|
|
120
|
-
|
|
150
|
+
create(:user) do |user|
|
|
121
151
|
user.posts.create(attributes_for(:post))
|
|
122
152
|
end
|
|
123
153
|
```
|
|
@@ -126,55 +156,11 @@ No matter which strategy is used, it's possible to override the defined attribut
|
|
|
126
156
|
|
|
127
157
|
```ruby
|
|
128
158
|
# Build a User instance and override the first_name property
|
|
129
|
-
user =
|
|
159
|
+
user = build(:user, first_name: "Joe")
|
|
130
160
|
user.first_name
|
|
131
161
|
# => "Joe"
|
|
132
162
|
```
|
|
133
163
|
|
|
134
|
-
If repeating "FactoryGirl" is too verbose for you, you can mix the syntax methods in:
|
|
135
|
-
|
|
136
|
-
```ruby
|
|
137
|
-
# rspec
|
|
138
|
-
RSpec.configure do |config|
|
|
139
|
-
config.include FactoryGirl::Syntax::Methods
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Test::Unit
|
|
143
|
-
class Test::Unit::TestCase
|
|
144
|
-
include FactoryGirl::Syntax::Methods
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# Cucumber
|
|
148
|
-
World(FactoryGirl::Syntax::Methods)
|
|
149
|
-
|
|
150
|
-
# MiniTest
|
|
151
|
-
class MiniTest::Unit::TestCase
|
|
152
|
-
include FactoryGirl::Syntax::Methods
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# MiniTest::Spec
|
|
156
|
-
class MiniTest::Spec
|
|
157
|
-
include FactoryGirl::Syntax::Methods
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
# minitest-rails
|
|
161
|
-
class MiniTest::Rails::ActiveSupport::TestCase
|
|
162
|
-
include FactoryGirl::Syntax::Methods
|
|
163
|
-
end
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
This allows you to use the core set of syntax methods (`build`,
|
|
167
|
-
`build_stubbed`, `create`, `attributes_for`, and their `*_list` counterparts)
|
|
168
|
-
without having to call them on FactoryGirl directly:
|
|
169
|
-
|
|
170
|
-
```ruby
|
|
171
|
-
describe User, "#full_name" do
|
|
172
|
-
subject { create(:user, first_name: "John", last_name: "Doe") }
|
|
173
|
-
|
|
174
|
-
its(:full_name) { should eq "John Doe" }
|
|
175
|
-
end
|
|
176
|
-
```
|
|
177
|
-
|
|
178
164
|
Lazy Attributes
|
|
179
165
|
---------------
|
|
180
166
|
|
|
@@ -192,24 +178,6 @@ factory :user do
|
|
|
192
178
|
end
|
|
193
179
|
```
|
|
194
180
|
|
|
195
|
-
In addition to running other methods dynamically, you can use FactoryGirl's
|
|
196
|
-
syntax methods (like `build`, `create`, and `generate`) within dynamic
|
|
197
|
-
attributes without having to prefix the call with `FactoryGirl.`. This allows
|
|
198
|
-
you to do:
|
|
199
|
-
|
|
200
|
-
```ruby
|
|
201
|
-
sequence(:random_string) {|n| LoremIpsum.generate }
|
|
202
|
-
|
|
203
|
-
factory :post do
|
|
204
|
-
title { generate(:random_string) } # instead of FactoryGirl.generate(:random_string)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
factory :comment do
|
|
208
|
-
post
|
|
209
|
-
body { generate(:random_string) } # instead of FactoryGirl.generate(:random_string)
|
|
210
|
-
end
|
|
211
|
-
```
|
|
212
|
-
|
|
213
181
|
Aliases
|
|
214
182
|
-------
|
|
215
183
|
|
|
@@ -250,7 +218,7 @@ factory :user do
|
|
|
250
218
|
email { "#{first_name}.#{last_name}@example.com".downcase }
|
|
251
219
|
end
|
|
252
220
|
|
|
253
|
-
|
|
221
|
+
create(:user, last_name: "Doe").email
|
|
254
222
|
# => "joe.doe@example.com"
|
|
255
223
|
```
|
|
256
224
|
|
|
@@ -274,7 +242,7 @@ factory :user do
|
|
|
274
242
|
end
|
|
275
243
|
end
|
|
276
244
|
|
|
277
|
-
|
|
245
|
+
create(:user, upcased: true).name
|
|
278
246
|
#=> "JOHN DOE - ROCKSTAR"
|
|
279
247
|
```
|
|
280
248
|
|
|
@@ -282,8 +250,8 @@ Static and dynamic attributes can be ignored. Ignored attributes will be ignored
|
|
|
282
250
|
within attributes\_for and won't be set on the model, even if the attribute
|
|
283
251
|
exists or you attempt to override it.
|
|
284
252
|
|
|
285
|
-
Within
|
|
286
|
-
you would expect. If you need to access the evaluator in a
|
|
253
|
+
Within factory_girl's dynamic attributes, you can access ignored attributes as
|
|
254
|
+
you would expect. If you need to access the evaluator in a factory_girl callback,
|
|
287
255
|
you'll need to declare a second block argument (for the evaluator) and access
|
|
288
256
|
ignored attributes from there.
|
|
289
257
|
|
|
@@ -312,12 +280,12 @@ The behavior of the association method varies depending on the build strategy us
|
|
|
312
280
|
|
|
313
281
|
```ruby
|
|
314
282
|
# Builds and saves a User and a Post
|
|
315
|
-
post =
|
|
283
|
+
post = create(:post)
|
|
316
284
|
post.new_record? # => false
|
|
317
285
|
post.author.new_record? # => false
|
|
318
286
|
|
|
319
287
|
# Builds and saves a User, and then builds but does not save a Post
|
|
320
|
-
post =
|
|
288
|
+
post = build(:post)
|
|
321
289
|
post.new_record? # => true
|
|
322
290
|
post.author.new_record? # => false
|
|
323
291
|
```
|
|
@@ -331,7 +299,7 @@ factory :post do
|
|
|
331
299
|
end
|
|
332
300
|
|
|
333
301
|
# Builds a User, and then builds a Post, but does not save either
|
|
334
|
-
post =
|
|
302
|
+
post = build(:post)
|
|
335
303
|
post.new_record? # => true
|
|
336
304
|
post.author.new_record? # => true
|
|
337
305
|
```
|
|
@@ -375,7 +343,7 @@ FactoryGirl.define do
|
|
|
375
343
|
# attributes; `create_list`'s second argument is the number of records
|
|
376
344
|
# to create and we make sure the user is associated properly to the post
|
|
377
345
|
after(:create) do |user, evaluator|
|
|
378
|
-
|
|
346
|
+
create_list(:post, evaluator.posts_count, user: user)
|
|
379
347
|
end
|
|
380
348
|
end
|
|
381
349
|
end
|
|
@@ -385,9 +353,9 @@ end
|
|
|
385
353
|
This allows us to do:
|
|
386
354
|
|
|
387
355
|
```ruby
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
356
|
+
create(:user).posts.length # 0
|
|
357
|
+
create(:user_with_posts).posts.length # 5
|
|
358
|
+
create(:user_with_posts, posts_count: 15).posts.length # 15
|
|
391
359
|
```
|
|
392
360
|
|
|
393
361
|
Inheritance
|
|
@@ -404,7 +372,7 @@ factory :post do
|
|
|
404
372
|
end
|
|
405
373
|
end
|
|
406
374
|
|
|
407
|
-
approved_post =
|
|
375
|
+
approved_post = create(:approved_post)
|
|
408
376
|
approved_post.title # => "A title"
|
|
409
377
|
approved_post.approved # => true
|
|
410
378
|
```
|
|
@@ -432,7 +400,7 @@ Sequences
|
|
|
432
400
|
Unique values in a specific format (for example, e-mail addresses) can be
|
|
433
401
|
generated using sequences. Sequences are defined by calling sequence in a
|
|
434
402
|
definition block, and values in a sequence are generated by calling
|
|
435
|
-
|
|
403
|
+
`generate`:
|
|
436
404
|
|
|
437
405
|
```ruby
|
|
438
406
|
# Defines a new sequence
|
|
@@ -442,10 +410,10 @@ FactoryGirl.define do
|
|
|
442
410
|
end
|
|
443
411
|
end
|
|
444
412
|
|
|
445
|
-
|
|
413
|
+
generate :email
|
|
446
414
|
# => "person1@example.com"
|
|
447
415
|
|
|
448
|
-
|
|
416
|
+
generate :email
|
|
449
417
|
# => "person2@example.com"
|
|
450
418
|
```
|
|
451
419
|
|
|
@@ -470,7 +438,7 @@ a particular factory:
|
|
|
470
438
|
|
|
471
439
|
```ruby
|
|
472
440
|
factory :user do
|
|
473
|
-
sequence(:email) {|n| "person#{n}@example.com" }
|
|
441
|
+
sequence(:email) { |n| "person#{n}@example.com" }
|
|
474
442
|
end
|
|
475
443
|
```
|
|
476
444
|
|
|
@@ -478,7 +446,7 @@ You can also override the initial value:
|
|
|
478
446
|
|
|
479
447
|
```ruby
|
|
480
448
|
factory :user do
|
|
481
|
-
sequence(:email, 1000) {|n| "person#{n}@example.com" }
|
|
449
|
+
sequence(:email, 1000) { |n| "person#{n}@example.com" }
|
|
482
450
|
end
|
|
483
451
|
```
|
|
484
452
|
|
|
@@ -494,18 +462,18 @@ Sequences can also have aliases. The sequence aliases share the same counter:
|
|
|
494
462
|
|
|
495
463
|
```ruby
|
|
496
464
|
factory :user do
|
|
497
|
-
sequence(:email, 1000, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
|
|
465
|
+
sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
|
|
498
466
|
end
|
|
499
467
|
|
|
500
468
|
# will increase value counter for :email which is shared by :sender and :receiver
|
|
501
|
-
|
|
469
|
+
generate(:sender)
|
|
502
470
|
```
|
|
503
471
|
|
|
504
472
|
Define aliases and use default value (1) for the counter
|
|
505
473
|
|
|
506
474
|
```ruby
|
|
507
475
|
factory :user do
|
|
508
|
-
sequence(:email, aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
|
|
476
|
+
sequence(:email, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
|
|
509
477
|
end
|
|
510
478
|
```
|
|
511
479
|
|
|
@@ -513,7 +481,7 @@ Setting the value:
|
|
|
513
481
|
|
|
514
482
|
```ruby
|
|
515
483
|
factory :user do
|
|
516
|
-
sequence(:email, 'a', aliases: [:sender, :receiver]) {|n| "person#{n}@example.com" }
|
|
484
|
+
sequence(:email, 'a', aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
|
|
517
485
|
end
|
|
518
486
|
```
|
|
519
487
|
|
|
@@ -617,7 +585,7 @@ factory :user do
|
|
|
617
585
|
end
|
|
618
586
|
```
|
|
619
587
|
|
|
620
|
-
Traits can also be passed in as a list of symbols when you construct an instance from
|
|
588
|
+
Traits can also be passed in as a list of symbols when you construct an instance from factory_girl.
|
|
621
589
|
|
|
622
590
|
```ruby
|
|
623
591
|
factory :user do
|
|
@@ -634,7 +602,7 @@ factory :user do
|
|
|
634
602
|
end
|
|
635
603
|
|
|
636
604
|
# creates an admin user with gender "Male" and name "Jon Snow"
|
|
637
|
-
|
|
605
|
+
create(:user, :admin, :male, name: "Jon Snow")
|
|
638
606
|
```
|
|
639
607
|
|
|
640
608
|
This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
|
|
@@ -653,7 +621,7 @@ factory :user do
|
|
|
653
621
|
end
|
|
654
622
|
|
|
655
623
|
# creates 3 admin users with gender "Male" and name "Jon Snow"
|
|
656
|
-
|
|
624
|
+
create_list(:user, 3, :admin, :male, name: "Jon Snow")
|
|
657
625
|
```
|
|
658
626
|
|
|
659
627
|
Traits can be used with associations easily too:
|
|
@@ -672,7 +640,7 @@ factory :post do
|
|
|
672
640
|
end
|
|
673
641
|
|
|
674
642
|
# creates an admin user with name "John Doe"
|
|
675
|
-
|
|
643
|
+
create(:post).user
|
|
676
644
|
```
|
|
677
645
|
|
|
678
646
|
When you're using association names that're different than the factory:
|
|
@@ -693,7 +661,7 @@ factory :post do
|
|
|
693
661
|
end
|
|
694
662
|
|
|
695
663
|
# creates an admin user with name "John Doe"
|
|
696
|
-
|
|
664
|
+
create(:post).author
|
|
697
665
|
```
|
|
698
666
|
|
|
699
667
|
Finally, traits can be used within other traits to mix in their attributes.
|
|
@@ -752,7 +720,7 @@ factory :user do
|
|
|
752
720
|
end
|
|
753
721
|
```
|
|
754
722
|
|
|
755
|
-
Calling
|
|
723
|
+
Calling `create` will invoke both `after_build` and `after_create` callbacks.
|
|
756
724
|
|
|
757
725
|
Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
|
|
758
726
|
|
|
@@ -771,8 +739,8 @@ To override callbacks for all factories, define them within the
|
|
|
771
739
|
|
|
772
740
|
```ruby
|
|
773
741
|
FactoryGirl.define do
|
|
774
|
-
after(:build) {|object| puts "Built #{object}" }
|
|
775
|
-
after(:create) {|object| AuditLog.create(attrs: object.attributes) }
|
|
742
|
+
after(:build) { |object| puts "Built #{object}" }
|
|
743
|
+
after(:create) { |object| AuditLog.create(attrs: object.attributes) }
|
|
776
744
|
|
|
777
745
|
factory :user do
|
|
778
746
|
name "John Doe"
|
|
@@ -797,7 +765,7 @@ FactoryGirl.define do
|
|
|
797
765
|
end
|
|
798
766
|
end
|
|
799
767
|
|
|
800
|
-
|
|
768
|
+
create(:user) # creates the user and confirms it
|
|
801
769
|
```
|
|
802
770
|
|
|
803
771
|
Modifying factories
|
|
@@ -812,7 +780,7 @@ If a gem were to give you a User factory:
|
|
|
812
780
|
FactoryGirl.define do
|
|
813
781
|
factory :user do
|
|
814
782
|
full_name "John Doe"
|
|
815
|
-
sequence(:username) {|n| "user#{n}" }
|
|
783
|
+
sequence(:username) { |n| "user#{n}" }
|
|
816
784
|
password "password"
|
|
817
785
|
end
|
|
818
786
|
end
|
|
@@ -857,22 +825,22 @@ Building or Creating Multiple Records
|
|
|
857
825
|
Sometimes, you'll want to create or build multiple instances of a factory at once.
|
|
858
826
|
|
|
859
827
|
```ruby
|
|
860
|
-
built_users =
|
|
861
|
-
created_users =
|
|
828
|
+
built_users = build_list(:user, 25)
|
|
829
|
+
created_users = create_list(:user, 25)
|
|
862
830
|
```
|
|
863
831
|
|
|
864
832
|
These methods will build or create a specific amount of factories and return them as an array.
|
|
865
833
|
To set the attributes for each of the factories, you can pass in a hash as you normally would.
|
|
866
834
|
|
|
867
835
|
```ruby
|
|
868
|
-
twenty_year_olds =
|
|
836
|
+
twenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)
|
|
869
837
|
```
|
|
870
838
|
|
|
871
839
|
There's also a set of `*_pair` methods for creating two records at a time:
|
|
872
840
|
|
|
873
841
|
```ruby
|
|
874
|
-
built_users =
|
|
875
|
-
created_users =
|
|
842
|
+
built_users = build_pair(:user) # array of two built users
|
|
843
|
+
created_users = create_pair(:user) # array of two created users
|
|
876
844
|
```
|
|
877
845
|
|
|
878
846
|
Custom Construction
|
|
@@ -894,7 +862,7 @@ class User
|
|
|
894
862
|
end
|
|
895
863
|
|
|
896
864
|
# factories.rb
|
|
897
|
-
sequence(:email) {|n| "person#{n}@example.com" }
|
|
865
|
+
sequence(:email) { |n| "person#{n}@example.com" }
|
|
898
866
|
|
|
899
867
|
factory :user do
|
|
900
868
|
ignore do
|
|
@@ -905,7 +873,7 @@ factory :user do
|
|
|
905
873
|
initialize_with { new(name) }
|
|
906
874
|
end
|
|
907
875
|
|
|
908
|
-
|
|
876
|
+
build(:user).name # Jane Doe
|
|
909
877
|
```
|
|
910
878
|
|
|
911
879
|
Notice that I ignored the `name` attribute. If you don't want attributes
|
|
@@ -981,12 +949,12 @@ FactoryGirl.define do
|
|
|
981
949
|
end
|
|
982
950
|
end
|
|
983
951
|
|
|
984
|
-
|
|
952
|
+
build(:user)
|
|
985
953
|
# runs
|
|
986
954
|
User.new('value')
|
|
987
955
|
```
|
|
988
956
|
|
|
989
|
-
This prevents duplicate assignment; in versions of
|
|
957
|
+
This prevents duplicate assignment; in versions of factory_girl before 4.0, it
|
|
990
958
|
would run this:
|
|
991
959
|
|
|
992
960
|
```ruby
|
|
@@ -998,7 +966,7 @@ FactoryGirl.define do
|
|
|
998
966
|
end
|
|
999
967
|
end
|
|
1000
968
|
|
|
1001
|
-
|
|
969
|
+
build(:user)
|
|
1002
970
|
# runs
|
|
1003
971
|
user = User.new('value')
|
|
1004
972
|
user.name = 'value'
|
|
@@ -1081,9 +1049,9 @@ FactoryGirl.register_strategy(:json, JsonStrategy)
|
|
|
1081
1049
|
|
|
1082
1050
|
FactoryGirl.define do
|
|
1083
1051
|
factory :user do
|
|
1084
|
-
before(:json) {|user| do_something_to(user) }
|
|
1085
|
-
after(:json) {|user_json| do_something_to(user_json) }
|
|
1086
|
-
callback(:make_json_awesome) {|user_json| do_something_to(user_json) }
|
|
1052
|
+
before(:json) { |user| do_something_to(user) }
|
|
1053
|
+
after(:json) { |user_json| do_something_to(user_json) }
|
|
1054
|
+
callback(:make_json_awesome) { |user_json| do_something_to(user_json) }
|
|
1087
1055
|
end
|
|
1088
1056
|
end
|
|
1089
1057
|
```
|
|
@@ -1097,7 +1065,7 @@ may not always be ideal, you can override that behavior by defining
|
|
|
1097
1065
|
|
|
1098
1066
|
```ruby
|
|
1099
1067
|
factory :different_orm_model do
|
|
1100
|
-
to_create {|instance| instance.persist! }
|
|
1068
|
+
to_create { |instance| instance.persist! }
|
|
1101
1069
|
end
|
|
1102
1070
|
```
|
|
1103
1071
|
|
|
@@ -1115,7 +1083,7 @@ To override `to_create` for all factories, define it within the
|
|
|
1115
1083
|
|
|
1116
1084
|
```ruby
|
|
1117
1085
|
FactoryGirl.define do
|
|
1118
|
-
to_create {|instance| instance.persist! }
|
|
1086
|
+
to_create { |instance| instance.persist! }
|
|
1119
1087
|
|
|
1120
1088
|
|
|
1121
1089
|
factory :user do
|
|
@@ -1186,7 +1154,7 @@ end
|
|
|
1186
1154
|
The error occurs during the run of the test suite:
|
|
1187
1155
|
|
|
1188
1156
|
```
|
|
1189
|
-
Failure/Error: united_states =
|
|
1157
|
+
Failure/Error: united_states = create(:united_states)
|
|
1190
1158
|
ActiveRecord::AssociationTypeMismatch:
|
|
1191
1159
|
LocationGroup(#70251250797320) expected, got LocationGroup(#70251200725840)
|
|
1192
1160
|
```
|
|
@@ -1199,3 +1167,41 @@ RSpec.configure do |config|
|
|
|
1199
1167
|
config.before(:suite) { FactoryGirl.reload }
|
|
1200
1168
|
end
|
|
1201
1169
|
```
|
|
1170
|
+
|
|
1171
|
+
Using Without Bundler
|
|
1172
|
+
---------------------
|
|
1173
|
+
|
|
1174
|
+
If you're not using Bundler, be sure to have the gem installed and call:
|
|
1175
|
+
|
|
1176
|
+
```ruby
|
|
1177
|
+
require 'factory_girl'
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
Once required, assuming you have a directory structure of `spec/factories` or
|
|
1181
|
+
`test/factories`, all you'll need to do is run
|
|
1182
|
+
|
|
1183
|
+
```ruby
|
|
1184
|
+
FactoryGirl.find_definitions
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
If you're using a separate directory structure for your factories, you can
|
|
1188
|
+
change the definition file paths before trying to find definitions:
|
|
1189
|
+
|
|
1190
|
+
```ruby
|
|
1191
|
+
FactoryGirl.definition_file_paths = %w(custom_factories_directory)
|
|
1192
|
+
FactoryGirl.find_definitions
|
|
1193
|
+
```
|
|
1194
|
+
|
|
1195
|
+
If you don't have a separate directory of factories and would like to define
|
|
1196
|
+
them inline, that's possible as well:
|
|
1197
|
+
|
|
1198
|
+
```ruby
|
|
1199
|
+
require 'factory_girl'
|
|
1200
|
+
|
|
1201
|
+
FactoryGirl.define do
|
|
1202
|
+
factory :user do
|
|
1203
|
+
name 'John Doe'
|
|
1204
|
+
date_of_birth { 21.years.ago }
|
|
1205
|
+
end
|
|
1206
|
+
end
|
|
1207
|
+
```
|