factory_bot 5.0.2 → 6.1.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/CONTRIBUTING.md +52 -13
- data/GETTING_STARTED.md +453 -78
- data/NEWS.md +40 -0
- data/README.md +17 -16
- data/lib/factory_bot.rb +21 -93
- data/lib/factory_bot/aliases.rb +3 -3
- data/lib/factory_bot/attribute/association.rb +2 -2
- data/lib/factory_bot/attribute/dynamic.rb +2 -1
- data/lib/factory_bot/attribute_assigner.rb +8 -9
- data/lib/factory_bot/attribute_list.rb +1 -1
- data/lib/factory_bot/callback.rb +2 -10
- data/lib/factory_bot/configuration.rb +6 -6
- data/lib/factory_bot/declaration.rb +1 -1
- data/lib/factory_bot/declaration/association.rb +30 -2
- data/lib/factory_bot/declaration/implicit.rb +4 -1
- data/lib/factory_bot/declaration_list.rb +2 -2
- data/lib/factory_bot/decorator.rb +18 -6
- data/lib/factory_bot/decorator/invocation_tracker.rb +10 -3
- data/lib/factory_bot/definition.rb +51 -18
- data/lib/factory_bot/definition_hierarchy.rb +1 -11
- data/lib/factory_bot/definition_proxy.rb +77 -12
- data/lib/factory_bot/enum.rb +27 -0
- data/lib/factory_bot/errors.rb +3 -0
- data/lib/factory_bot/evaluator.rb +20 -12
- data/lib/factory_bot/evaluator_class_definer.rb +1 -1
- data/lib/factory_bot/factory.rb +13 -13
- data/lib/factory_bot/factory_runner.rb +4 -4
- data/lib/factory_bot/find_definitions.rb +1 -1
- data/lib/factory_bot/internal.rb +68 -1
- data/lib/factory_bot/linter.rb +9 -13
- data/lib/factory_bot/null_factory.rb +10 -4
- data/lib/factory_bot/null_object.rb +2 -6
- data/lib/factory_bot/registry.rb +4 -4
- data/lib/factory_bot/reload.rb +1 -2
- data/lib/factory_bot/sequence.rb +5 -5
- data/lib/factory_bot/strategy/null.rb +4 -2
- data/lib/factory_bot/strategy/stub.rb +16 -5
- data/lib/factory_bot/strategy_calculator.rb +1 -1
- data/lib/factory_bot/strategy_syntax_method_registrar.rb +12 -1
- data/lib/factory_bot/syntax/default.rb +11 -23
- data/lib/factory_bot/syntax/methods.rb +3 -3
- data/lib/factory_bot/trait.rb +5 -3
- data/lib/factory_bot/version.rb +1 -1
- metadata +9 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe33ad3bb5d907e38ceac543f969484fb0ec67a4708a701cdfea0696d4a292c4
|
4
|
+
data.tar.gz: 54cdb44f4ac7782360c8e9efd02ac46f40336d00c34a5767d5d7fc0f86f8d7a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdc3ec9def71e797058fb13cff95b911eceb61d1488f193ef1bfb6bdf12c6c7835d1f67dc1885d5539e6da7135f04e4a417a16fbc60cbc0c4d60056a1948c89d
|
7
|
+
data.tar.gz: 2f04ab1a184266a86cf8510be688b8a01b0dd570615d25e314176b4492f9635053596636aa4ec9ab8133e86e4c9f630acdb52468c01ea1bfd2fb8777fc27b2ab
|
data/CONTRIBUTING.md
CHANGED
@@ -12,7 +12,7 @@ Here are some ways *you* can contribute:
|
|
12
12
|
* by suggesting new features
|
13
13
|
* by writing or editing documentation
|
14
14
|
* by writing specifications
|
15
|
-
* by writing code ( **no patch is too small** : fix typos, add comments,
|
15
|
+
* by writing code ( **no patch is too small** : fix typos, add comments, etc. )
|
16
16
|
* by refactoring code
|
17
17
|
* by closing [issues][]
|
18
18
|
* by reviewing patches
|
@@ -23,13 +23,10 @@ Here are some ways *you* can contribute:
|
|
23
23
|
|
24
24
|
* We use the [GitHub issue tracker][issues] to track bugs and features.
|
25
25
|
* Before submitting a bug report or feature request, check to make sure it hasn't
|
26
|
-
already been submitted.
|
27
|
-
* When submitting a bug report, please include a [
|
28
|
-
|
29
|
-
|
30
|
-
should include a pull request with failing specs.
|
31
|
-
|
32
|
-
[gist]: https://gist.github.com/
|
26
|
+
already been submitted.
|
27
|
+
* When submitting a bug report, please include a [reproduction script] and any
|
28
|
+
other details that may be necessary to reproduce the bug, including your gem
|
29
|
+
version, Ruby version, and operating system.
|
33
30
|
|
34
31
|
## Cleaning up issues
|
35
32
|
|
@@ -40,21 +37,63 @@ already been submitted.
|
|
40
37
|
We will happily reopen the issue.
|
41
38
|
|
42
39
|
## Submitting a Pull Request
|
40
|
+
|
43
41
|
1. [Fork][fork] the [official repository][repo].
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
1. [Create a topic branch.][branch]
|
43
|
+
1. Implement your feature or bug fix.
|
44
|
+
1. Add, commit, and push your changes.
|
45
|
+
1. [Submit a pull request.][pr]
|
46
|
+
|
47
|
+
### Notes
|
48
48
|
|
49
|
-
## Notes
|
50
49
|
* Please add tests if you changed code. Contributions without tests won't be accepted.
|
51
50
|
* If you don't know how to add tests, please put in a PR and leave a comment
|
52
51
|
asking for help. We love helping!
|
53
52
|
* Please don't update the Gem version.
|
54
53
|
|
54
|
+
## Running the test suite
|
55
|
+
|
56
|
+
The default rake task will run the full test suite and [standard]:
|
57
|
+
|
58
|
+
```sh
|
59
|
+
bundle exec rake
|
60
|
+
```
|
61
|
+
|
62
|
+
You can also run a single group of tests (unit, spec, or feature)
|
63
|
+
|
64
|
+
```sh
|
65
|
+
bundle exec rake spec:unit
|
66
|
+
bundle exec rake spec:acceptance
|
67
|
+
bundle exec rake features
|
68
|
+
```
|
69
|
+
|
70
|
+
To run an individual rspec test, you can provide a path and line number:
|
71
|
+
|
72
|
+
```sh
|
73
|
+
bundle exec rspec spec/path/to/spec.rb:123
|
74
|
+
```
|
75
|
+
|
76
|
+
You can run tests with a specific version of rails via [appraisal]. To run
|
77
|
+
the default rake task against Rails 6, for example:
|
78
|
+
|
79
|
+
```sh
|
80
|
+
bundle exec appraisal 6.0 rake
|
81
|
+
```
|
82
|
+
|
83
|
+
## Formatting
|
84
|
+
|
85
|
+
Use [standard] to automatically format your code:
|
86
|
+
|
87
|
+
```sh
|
88
|
+
bundle exec rake standard:fix
|
89
|
+
```
|
90
|
+
|
55
91
|
[repo]: https://github.com/thoughtbot/factory_bot/tree/master
|
56
92
|
[fork]: https://help.github.com/articles/fork-a-repo/
|
57
93
|
[branch]: https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/
|
58
94
|
[pr]: https://help.github.com/articles/using-pull-requests/
|
95
|
+
[standard]: https://github.com/testdouble/standard
|
96
|
+
[appraisal]: https://github.com/thoughtbot/appraisal
|
97
|
+
[reproduction script]: https://github.com/thoughtbot/factory_bot/blob/master/.github/REPRODUCTION_SCRIPT.rb
|
59
98
|
|
60
99
|
Inspired by https://github.com/middleman/middleman-heroku/blob/master/CONTRIBUTING.md
|
data/GETTING_STARTED.md
CHANGED
@@ -1,8 +1,88 @@
|
|
1
1
|
Getting Started
|
2
2
|
===============
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
* [Setup](#setup)
|
5
|
+
+ [Update Your Gemfile](#update-your-gemfile)
|
6
|
+
+ [Configure your test suite](#configure-your-test-suite)
|
7
|
+
- [RSpec](#rspec)
|
8
|
+
- [Test::Unit](#testunit)
|
9
|
+
- [Cucumber](#cucumber)
|
10
|
+
- [Spinach](#spinach)
|
11
|
+
- [Minitest](#minitest)
|
12
|
+
- [Minitest::Spec](#minitestspec)
|
13
|
+
- [minitest-rails](#minitest-rails)
|
14
|
+
* [Defining factories](#defining-factories)
|
15
|
+
+ [Factory name and attributes](#factory-name-and-attributes)
|
16
|
+
+ [Specifying the class explicitly](#specifying-the-class-explicitly)
|
17
|
+
+ [Hash attributes](#hash-attributes)
|
18
|
+
+ [Best practices](#best-practices)
|
19
|
+
+ [Definition file paths](#definition-file-paths)
|
20
|
+
+ [Static Attributes](#static-attributes)
|
21
|
+
* [Using factories](#using-factories)
|
22
|
+
+ [Build strategies](#build-strategies)
|
23
|
+
+ [Attribute overrides](#attribute-overrides)
|
24
|
+
+ [`build_stubbed` and `Marshal.dump`](#build_stubbed-and-marshaldump)
|
25
|
+
* [Aliases](#aliases)
|
26
|
+
* [Dependent Attributes](#dependent-attributes)
|
27
|
+
* [Transient Attributes](#transient-attributes)
|
28
|
+
+ [With other attributes](#with-other-attributes)
|
29
|
+
+ [With `attributes_for`](#with-attributes_for)
|
30
|
+
+ [With callbacks](#with-callbacks)
|
31
|
+
+ [With associations](#with-associations)
|
32
|
+
* [Method Name / Reserved Word Attributes](#method-name--reserved-word-attributes)
|
33
|
+
* [Inheritance](#inheritance)
|
34
|
+
+ [Nested factories](#nested-factories)
|
35
|
+
+ [Assigning parent explicitly](#assigning-parent-explicitly)
|
36
|
+
+ [Best practices](#best-practices-1)
|
37
|
+
* [Associations](#associations)
|
38
|
+
+ [Implicit definition](#implicit-definition)
|
39
|
+
+ [Explicit definition](#explicit-definition)
|
40
|
+
+ [Specifying the factory](#specifying-the-factory)
|
41
|
+
+ [Overriding attributes](#overriding-attributes)
|
42
|
+
+ [Build strategies](#build-strategies-1)
|
43
|
+
+ [`has_many` associations](#has_many-associations)
|
44
|
+
+ [`has_and_belongs_to_many` associations](#has_and_belongs_to_many-associations)
|
45
|
+
+ [Polymorphic associations](#polymorphic-associations)
|
46
|
+
* [Sequences](#sequences)
|
47
|
+
+ [Global sequences](#global-sequences)
|
48
|
+
+ [With dynamic attributes](#with-dynamic-attributes)
|
49
|
+
+ [As implicit attributes](#as-implicit-attributes)
|
50
|
+
+ [Inline sequences](#inline-sequences)
|
51
|
+
+ [Initial value](#initial-value)
|
52
|
+
+ [Without a block](#without-a-block)
|
53
|
+
+ [Aliases](#aliases-1)
|
54
|
+
+ [Rewinding](#rewinding)
|
55
|
+
+ [Uniqueness](#uniqueness)
|
56
|
+
* [Traits](#traits)
|
57
|
+
+ [Defining traits](#defining-traits)
|
58
|
+
+ [As implicit attributes](#as-implicit-attributes-1)
|
59
|
+
+ [Attribute precedence](#attribute-precedence)
|
60
|
+
+ [In child factories](#in-child-factories)
|
61
|
+
+ [Using traits](#using-traits)
|
62
|
+
+ [With associations](#with-associations-1)
|
63
|
+
+ [Traits within traits](#traits-within-traits)
|
64
|
+
+ [With transient attributes](#with-transient-attributes)
|
65
|
+
+ [Enum traits](#enum-traits)
|
66
|
+
* [Callbacks](#callbacks)
|
67
|
+
+ [Default callbacks](#default-callbacks)
|
68
|
+
+ [Multiple callbacks](#multiple-callbacks)
|
69
|
+
+ [Global callbacks](#global-callbacks)
|
70
|
+
+ [Symbol#to_proc](#symbolto_proc)
|
71
|
+
* [Modifying factories](#modifying-factories)
|
72
|
+
* [Building or Creating Multiple Records](#building-or-creating-multiple-records)
|
73
|
+
* [Linting Factories](#linting-factories)
|
74
|
+
* [Custom Construction](#custom-construction)
|
75
|
+
* [Custom Strategies](#custom-strategies)
|
76
|
+
* [Custom Callbacks](#custom-callbacks)
|
77
|
+
* [Custom Methods to Persist Objects](#custom-methods-to-persist-objects)
|
78
|
+
* [ActiveSupport Instrumentation](#activesupport-instrumentation)
|
79
|
+
* [Rails Preloaders and RSpec](#rails-preloaders-and-rspec)
|
80
|
+
* [Using Without Bundler](#using-without-bundler)
|
81
|
+
|
82
|
+
Setup
|
83
|
+
-----
|
84
|
+
|
85
|
+
### Update Your Gemfile
|
6
86
|
|
7
87
|
If you're using Rails:
|
8
88
|
|
@@ -16,21 +96,13 @@ If you're *not* using Rails:
|
|
16
96
|
gem "factory_bot"
|
17
97
|
```
|
18
98
|
|
19
|
-
|
20
|
-
JRuby has to be used in 1.9 mode, for that, use JRUBY_OPTS environment variable:
|
21
|
-
|
22
|
-
```bash
|
23
|
-
export JRUBY_OPTS=--1.9
|
24
|
-
```
|
25
|
-
|
26
|
-
Once your Gemfile is updated, you'll want to update your bundle.
|
27
|
-
|
28
|
-
Configure your test suite
|
29
|
-
-------------------------
|
99
|
+
### Configure your test suite
|
30
100
|
|
31
|
-
|
101
|
+
#### RSpec
|
32
102
|
|
33
|
-
If you're using Rails
|
103
|
+
If you're using Rails, add the following configuration to
|
104
|
+
`spec/support/factory_bot.rb` and be sure to require that file in
|
105
|
+
`rails_helper.rb`:
|
34
106
|
|
35
107
|
```ruby
|
36
108
|
RSpec.configure do |config|
|
@@ -50,7 +122,7 @@ RSpec.configure do |config|
|
|
50
122
|
end
|
51
123
|
```
|
52
124
|
|
53
|
-
|
125
|
+
#### Test::Unit
|
54
126
|
|
55
127
|
```ruby
|
56
128
|
class Test::Unit::TestCase
|
@@ -58,14 +130,14 @@ class Test::Unit::TestCase
|
|
58
130
|
end
|
59
131
|
```
|
60
132
|
|
61
|
-
|
133
|
+
#### Cucumber
|
62
134
|
|
63
135
|
```ruby
|
64
136
|
# env.rb (Rails example location - RAILS_ROOT/features/support/env.rb)
|
65
137
|
World(FactoryBot::Syntax::Methods)
|
66
138
|
```
|
67
139
|
|
68
|
-
|
140
|
+
#### Spinach
|
69
141
|
|
70
142
|
```ruby
|
71
143
|
class Spinach::FeatureSteps
|
@@ -73,7 +145,7 @@ class Spinach::FeatureSteps
|
|
73
145
|
end
|
74
146
|
```
|
75
147
|
|
76
|
-
|
148
|
+
#### Minitest
|
77
149
|
|
78
150
|
```ruby
|
79
151
|
class Minitest::Unit::TestCase
|
@@ -81,7 +153,7 @@ class Minitest::Unit::TestCase
|
|
81
153
|
end
|
82
154
|
```
|
83
155
|
|
84
|
-
|
156
|
+
#### Minitest::Spec
|
85
157
|
|
86
158
|
```ruby
|
87
159
|
class Minitest::Spec
|
@@ -89,7 +161,7 @@ class Minitest::Spec
|
|
89
161
|
end
|
90
162
|
```
|
91
163
|
|
92
|
-
|
164
|
+
#### minitest-rails
|
93
165
|
|
94
166
|
```ruby
|
95
167
|
class ActiveSupport::TestCase
|
@@ -97,12 +169,16 @@ class ActiveSupport::TestCase
|
|
97
169
|
end
|
98
170
|
```
|
99
171
|
|
100
|
-
If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
|
172
|
+
If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
|
173
|
+
factory\_bot methods will need to be prefaced with `FactoryBot`.
|
101
174
|
|
102
175
|
Defining factories
|
103
176
|
------------------
|
104
177
|
|
105
|
-
|
178
|
+
### Factory name and attributes
|
179
|
+
|
180
|
+
Each factory has a name and a set of attributes. The name is used to guess the
|
181
|
+
class of the object by default:
|
106
182
|
|
107
183
|
```ruby
|
108
184
|
# This will guess the User class
|
@@ -115,6 +191,8 @@ FactoryBot.define do
|
|
115
191
|
end
|
116
192
|
```
|
117
193
|
|
194
|
+
### Specifying the class explicitly
|
195
|
+
|
118
196
|
It is also possible to explicitly specify the class:
|
119
197
|
|
120
198
|
```ruby
|
@@ -125,13 +203,15 @@ factory :admin, class: User
|
|
125
203
|
If the constant is not available
|
126
204
|
(if you are using a Rails engine that waits to load models, for example),
|
127
205
|
you can also pass a symbol or string,
|
128
|
-
which
|
206
|
+
which factory\_bot will constantize later, once you start building objects:
|
129
207
|
|
130
208
|
```ruby
|
131
209
|
# It's OK if Doorkeeper::AccessToken isn't loaded yet
|
132
210
|
factory :access_token, class: "Doorkeeper::AccessToken"
|
133
211
|
```
|
134
212
|
|
213
|
+
### Hash attributes
|
214
|
+
|
135
215
|
Because of the block syntax in Ruby, defining attributes as `Hash`es (for
|
136
216
|
serialized/JSON columns, for example) requires two sets of curly brackets:
|
137
217
|
|
@@ -141,10 +221,19 @@ factory :program do
|
|
141
221
|
end
|
142
222
|
```
|
143
223
|
|
144
|
-
|
224
|
+
### Best practices
|
225
|
+
|
226
|
+
It is recommended that you have one factory for each class that provides
|
227
|
+
the simplest set of attributes necessary to create an instance of that class. If
|
228
|
+
you're creating ActiveRecord objects, that means that you should only provide
|
229
|
+
attributes that are required through validations and that do not have defaults.
|
230
|
+
Other factories can be created through inheritance to cover common scenarios for
|
231
|
+
each class.
|
145
232
|
|
146
233
|
Attempting to define multiple factories with the same name will raise an error.
|
147
234
|
|
235
|
+
### Definition file paths
|
236
|
+
|
148
237
|
Factories can be defined anywhere, but will be automatically loaded after
|
149
238
|
calling `FactoryBot.find_definitions` if factories are defined in files at the
|
150
239
|
following locations:
|
@@ -154,10 +243,20 @@ following locations:
|
|
154
243
|
test/factories/*.rb
|
155
244
|
spec/factories/*.rb
|
156
245
|
|
246
|
+
### Static Attributes
|
247
|
+
|
248
|
+
Static attributes (without a block) are no longer available in factory\_bot 5.
|
249
|
+
You can read more about the decision to remove them in
|
250
|
+
[this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
|
251
|
+
|
252
|
+
|
157
253
|
Using factories
|
158
254
|
---------------
|
159
255
|
|
160
|
-
|
256
|
+
### Build strategies
|
257
|
+
|
258
|
+
factory\_bot supports several different build strategies: build, create,
|
259
|
+
attributes\_for and build\_stubbed:
|
161
260
|
|
162
261
|
```ruby
|
163
262
|
# Returns a User instance that's not saved
|
@@ -178,7 +277,10 @@ create(:user) do |user|
|
|
178
277
|
end
|
179
278
|
```
|
180
279
|
|
181
|
-
|
280
|
+
### Attribute overrides
|
281
|
+
|
282
|
+
No matter which strategy is used, it's possible to override the defined
|
283
|
+
attributes by passing a hash:
|
182
284
|
|
183
285
|
```ruby
|
184
286
|
# Build a User instance and override the first_name property
|
@@ -187,19 +289,20 @@ user.first_name
|
|
187
289
|
# => "Joe"
|
188
290
|
```
|
189
291
|
|
190
|
-
|
191
|
-
`Marshal.dump`, since factory_bot defines singleton methods on these objects.
|
192
|
-
|
193
|
-
Static Attributes
|
194
|
-
------------------
|
292
|
+
### `build_stubbed` and `Marshal.dump`
|
195
293
|
|
196
|
-
|
197
|
-
|
198
|
-
[this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
|
294
|
+
Note that objects created with `build_stubbed` cannot be serialized with
|
295
|
+
`Marshal.dump`, since factory\_bot defines singleton methods on these objects.
|
199
296
|
|
200
297
|
Aliases
|
201
298
|
-------
|
202
|
-
|
299
|
+
|
300
|
+
factory\_bot allows you to define aliases to existing factories to make them
|
301
|
+
easier to re-use. This could come in handy when, for example, your Post object
|
302
|
+
has an author attribute that actually refers to an instance of a User class.
|
303
|
+
While normally factory\_bot can infer the factory name from the association name,
|
304
|
+
in this case it will look for an author factory in vain. So, alias your user
|
305
|
+
factory so it can be used under alias names.
|
203
306
|
|
204
307
|
```ruby
|
205
308
|
factory :user, aliases: [:author, :commenter] do
|
@@ -244,35 +347,77 @@ create(:user, last_name: "Doe").email
|
|
244
347
|
Transient Attributes
|
245
348
|
--------------------
|
246
349
|
|
247
|
-
|
350
|
+
### With other attributes
|
351
|
+
|
352
|
+
There may be times where your code can be DRYed up by passing in transient
|
353
|
+
attributes to factories. You can access transient attributes within other
|
354
|
+
attributes (see [Dependent Attributes](#dependent-attributes)):
|
248
355
|
|
249
356
|
```ruby
|
250
357
|
factory :user do
|
251
358
|
transient do
|
252
359
|
rockstar { true }
|
253
|
-
upcased { false }
|
254
360
|
end
|
255
361
|
|
256
362
|
name { "John Doe#{" - Rockstar" if rockstar}" }
|
257
|
-
|
363
|
+
end
|
364
|
+
|
365
|
+
create(:user).name
|
366
|
+
#=> "John Doe - ROCKSTAR"
|
367
|
+
|
368
|
+
create(:user, rockstar: false).name
|
369
|
+
#=> "John Doe"
|
370
|
+
```
|
371
|
+
|
372
|
+
### With `attributes_for`
|
373
|
+
|
374
|
+
Transient attributes will be ignored within attributes\_for and won't be set on
|
375
|
+
the model, even if the attribute exists or you attempt to override it.
|
376
|
+
|
377
|
+
### With callbacks
|
378
|
+
|
379
|
+
If you need to access the evaluator in a factory\_bot callback,
|
380
|
+
you'll need to declare a second block argument (for the evaluator) and access
|
381
|
+
transient attributes from there.
|
382
|
+
|
383
|
+
```ruby
|
384
|
+
factory :user do
|
385
|
+
transient do
|
386
|
+
upcased { false }
|
387
|
+
end
|
388
|
+
|
389
|
+
name { "John Doe" }
|
258
390
|
|
259
391
|
after(:create) do |user, evaluator|
|
260
392
|
user.name.upcase! if evaluator.upcased
|
261
393
|
end
|
262
394
|
end
|
263
395
|
|
396
|
+
create(:user).name
|
397
|
+
#=> "John Doe"
|
398
|
+
|
264
399
|
create(:user, upcased: true).name
|
265
|
-
#=> "JOHN DOE
|
400
|
+
#=> "JOHN DOE"
|
266
401
|
```
|
267
402
|
|
268
|
-
|
269
|
-
set on the model,
|
270
|
-
even if the attribute exists or you attempt to override it.
|
403
|
+
### With associations
|
271
404
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
405
|
+
Transient [associations](#associations) are not supported in factory\_bot.
|
406
|
+
Associations within the transient block will be treated as regular,
|
407
|
+
non-transient associations.
|
408
|
+
|
409
|
+
If needed, you can generally work around this by building a factory within a
|
410
|
+
transient attribute:
|
411
|
+
|
412
|
+
```ruby
|
413
|
+
factory :post
|
414
|
+
|
415
|
+
factory :user do
|
416
|
+
transient do
|
417
|
+
post { build(:post) }
|
418
|
+
end
|
419
|
+
end
|
420
|
+
```
|
276
421
|
|
277
422
|
Method Name / Reserved Word Attributes
|
278
423
|
-------------------------------
|
@@ -293,7 +438,10 @@ end
|
|
293
438
|
Inheritance
|
294
439
|
-----------
|
295
440
|
|
296
|
-
|
441
|
+
### Nested factories
|
442
|
+
|
443
|
+
You can easily create multiple factories for the same class without repeating
|
444
|
+
common attributes by nesting factories:
|
297
445
|
|
298
446
|
```ruby
|
299
447
|
factory :post do
|
@@ -309,6 +457,8 @@ approved_post.title # => "A title"
|
|
309
457
|
approved_post.approved # => true
|
310
458
|
```
|
311
459
|
|
460
|
+
### Assigning parent explicitly
|
461
|
+
|
312
462
|
You can also assign the parent explicitly:
|
313
463
|
|
314
464
|
```ruby
|
@@ -321,6 +471,8 @@ factory :approved_post, parent: :post do
|
|
321
471
|
end
|
322
472
|
```
|
323
473
|
|
474
|
+
### Best practices
|
475
|
+
|
324
476
|
As mentioned above, it's good practice to define a basic factory for each class
|
325
477
|
with only the attributes required to create it. Then, create more specific
|
326
478
|
factories that inherit from this basic parent. Factory definitions are still
|
@@ -329,7 +481,10 @@ code, so keep them DRY.
|
|
329
481
|
Associations
|
330
482
|
------------
|
331
483
|
|
332
|
-
|
484
|
+
### Implicit definition
|
485
|
+
|
486
|
+
It's possible to set up associations within factories. If the factory name is
|
487
|
+
the same as the association name, the factory name can be left out.
|
333
488
|
|
334
489
|
```ruby
|
335
490
|
factory :post do
|
@@ -338,15 +493,66 @@ factory :post do
|
|
338
493
|
end
|
339
494
|
```
|
340
495
|
|
341
|
-
|
496
|
+
### Explicit definition
|
497
|
+
|
498
|
+
You can define associations explicitly. This can be handy especially when
|
499
|
+
[Overriding attributes](#overriding-attributes)
|
500
|
+
|
501
|
+
```ruby
|
502
|
+
factory :post do
|
503
|
+
# ...
|
504
|
+
association :author
|
505
|
+
end
|
506
|
+
```
|
507
|
+
|
508
|
+
### Specifying the factory
|
509
|
+
|
510
|
+
You can specify a different factory (although [Aliases](#aliases) might also
|
511
|
+
help you out here).
|
512
|
+
|
513
|
+
Implicitly:
|
514
|
+
|
515
|
+
```ruby
|
516
|
+
factory :post do
|
517
|
+
# ...
|
518
|
+
author factory: :user
|
519
|
+
end
|
520
|
+
```
|
521
|
+
|
522
|
+
Explicitly:
|
523
|
+
|
524
|
+
```ruby
|
525
|
+
factory :post do
|
526
|
+
# ...
|
527
|
+
association :author, factory: :user
|
528
|
+
end
|
529
|
+
```
|
530
|
+
|
531
|
+
### Overriding attributes
|
532
|
+
|
533
|
+
You can also override attributes.
|
534
|
+
|
535
|
+
Implicitly:
|
536
|
+
|
537
|
+
```ruby
|
538
|
+
factory :post do
|
539
|
+
# ...
|
540
|
+
author factory: :author, last_name: "Writely"
|
541
|
+
end
|
542
|
+
```
|
543
|
+
|
544
|
+
Explicitly:
|
545
|
+
|
342
546
|
|
343
547
|
```ruby
|
344
548
|
factory :post do
|
345
549
|
# ...
|
346
|
-
association :author,
|
550
|
+
association :author, last_name: "Writely"
|
347
551
|
end
|
348
552
|
```
|
349
553
|
|
554
|
+
### Build strategies
|
555
|
+
|
350
556
|
In factory\_bot 5, associations default to using the same build strategy as
|
351
557
|
their parent object:
|
352
558
|
|
@@ -387,7 +593,7 @@ post.new_record? # => true
|
|
387
593
|
post.author.new_record? # => false
|
388
594
|
```
|
389
595
|
|
390
|
-
To not save the associated object, specify strategy: :build in the factory:
|
596
|
+
To not save the associated object, specify `strategy: :build` in the factory:
|
391
597
|
|
392
598
|
```ruby
|
393
599
|
FactoryBot.use_parent_strategy = false
|
@@ -412,6 +618,8 @@ factory :post do
|
|
412
618
|
author strategy: :build # <<< this does *not* work; causes author_id to be nil
|
413
619
|
```
|
414
620
|
|
621
|
+
### `has_many` associations
|
622
|
+
|
415
623
|
Generating data for a `has_many` relationship is a bit more involved,
|
416
624
|
depending on the amount of flexibility desired, but here's a surefire example
|
417
625
|
of generating associated data.
|
@@ -457,6 +665,8 @@ create(:user_with_posts).posts.length # 5
|
|
457
665
|
create(:user_with_posts, posts_count: 15).posts.length # 15
|
458
666
|
```
|
459
667
|
|
668
|
+
### `has_and_belongs_to_many` associations
|
669
|
+
|
460
670
|
Generating data for a `has_and_belongs_to_many` relationship is very similar
|
461
671
|
to the above `has_many` relationship, with a small change, you need to pass an
|
462
672
|
array of objects to the model's pluralized attribute name rather than a single
|
@@ -508,22 +718,24 @@ create(:profile_with_languages).languages.length # 5
|
|
508
718
|
create(:profile_with_languages, languages_count: 15).languages.length # 15
|
509
719
|
```
|
510
720
|
|
721
|
+
### Polymorphic associations
|
722
|
+
|
511
723
|
Polymorphic associations can be handled with traits:
|
512
724
|
|
513
|
-
```
|
725
|
+
```ruby
|
514
726
|
FactoryBot.define do
|
515
727
|
factory :video
|
516
728
|
factory :photo
|
517
729
|
|
518
730
|
factory :comment do
|
519
|
-
for_photo
|
731
|
+
for_photo # default to the :for_photo trait if none is specified
|
520
732
|
|
521
733
|
trait :for_video do
|
522
|
-
association
|
734
|
+
association :commentable, factory: :video
|
523
735
|
end
|
524
736
|
|
525
737
|
trait :for_photo do
|
526
|
-
association
|
738
|
+
association :commentable, factory: :photo
|
527
739
|
end
|
528
740
|
end
|
529
741
|
end
|
@@ -531,7 +743,7 @@ end
|
|
531
743
|
|
532
744
|
This allows us to do:
|
533
745
|
|
534
|
-
```
|
746
|
+
```ruby
|
535
747
|
create(:comment)
|
536
748
|
create(:comment, :for_video)
|
537
749
|
create(:comment, :for_photo)
|
@@ -541,6 +753,8 @@ create(:comment, :for_photo)
|
|
541
753
|
Sequences
|
542
754
|
---------
|
543
755
|
|
756
|
+
### Global sequences
|
757
|
+
|
544
758
|
Unique values in a specific format (for example, e-mail addresses) can be
|
545
759
|
generated using sequences. Sequences are defined by calling `sequence` in a
|
546
760
|
definition block, and values in a sequence are generated by calling
|
@@ -561,6 +775,8 @@ generate :email
|
|
561
775
|
# => "person2@example.com"
|
562
776
|
```
|
563
777
|
|
778
|
+
### With dynamic attributes
|
779
|
+
|
564
780
|
Sequences can be used in dynamic attributes:
|
565
781
|
|
566
782
|
```ruby
|
@@ -569,6 +785,8 @@ factory :invite do
|
|
569
785
|
end
|
570
786
|
```
|
571
787
|
|
788
|
+
### As implicit attributes
|
789
|
+
|
572
790
|
Or as implicit attributes:
|
573
791
|
|
574
792
|
```ruby
|
@@ -580,6 +798,8 @@ end
|
|
580
798
|
Note that defining sequences as implicit attributes will not work if you have a
|
581
799
|
factory with the same name as the sequence.
|
582
800
|
|
801
|
+
### Inline sequences
|
802
|
+
|
583
803
|
And it's also possible to define an in-line sequence that is only used in
|
584
804
|
a particular factory:
|
585
805
|
|
@@ -589,7 +809,10 @@ factory :user do
|
|
589
809
|
end
|
590
810
|
```
|
591
811
|
|
592
|
-
|
812
|
+
### Initial value
|
813
|
+
|
814
|
+
You can override the initial value. Any value that response to the `#next`
|
815
|
+
method will work (e.g. 1, 2, 3, 'a', 'b', 'c')
|
593
816
|
|
594
817
|
```ruby
|
595
818
|
factory :user do
|
@@ -597,6 +820,8 @@ factory :user do
|
|
597
820
|
end
|
598
821
|
```
|
599
822
|
|
823
|
+
### Without a block
|
824
|
+
|
600
825
|
Without a block, the value will increment itself, starting at its initial value:
|
601
826
|
|
602
827
|
```ruby
|
@@ -605,6 +830,8 @@ factory :post do
|
|
605
830
|
end
|
606
831
|
```
|
607
832
|
|
833
|
+
### Aliases
|
834
|
+
|
608
835
|
Sequences can also have aliases. The sequence aliases share the same counter:
|
609
836
|
|
610
837
|
```ruby
|
@@ -634,6 +861,8 @@ end
|
|
634
861
|
|
635
862
|
The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
|
636
863
|
|
864
|
+
### Rewinding
|
865
|
+
|
637
866
|
Sequences can also be rewound with `FactoryBot.rewind_sequences`:
|
638
867
|
|
639
868
|
```ruby
|
@@ -650,9 +879,27 @@ generate(:email) # "person1@example.com"
|
|
650
879
|
|
651
880
|
This rewinds all registered sequences.
|
652
881
|
|
882
|
+
### Uniqueness
|
883
|
+
|
884
|
+
When working with uniqueness constraints, be careful not to pass in override values that will conflict with the generated sequence values.
|
885
|
+
|
886
|
+
In this example the email will be the same for both users. If email must be unique, this code will error:
|
887
|
+
|
888
|
+
```rb
|
889
|
+
factory :user do
|
890
|
+
sequence(:email) { |n| "person#{n}@example.com" }
|
891
|
+
end
|
892
|
+
|
893
|
+
FactoryBot.create(:user, email: "person1@example.com")
|
894
|
+
FactoryBot.create(:user)
|
895
|
+
```
|
896
|
+
|
897
|
+
|
653
898
|
Traits
|
654
899
|
------
|
655
900
|
|
901
|
+
### Defining traits
|
902
|
+
|
656
903
|
Traits allow you to group attributes together and then apply them
|
657
904
|
to any factory.
|
658
905
|
|
@@ -688,6 +935,8 @@ factory :story do
|
|
688
935
|
end
|
689
936
|
```
|
690
937
|
|
938
|
+
### As implicit attributes
|
939
|
+
|
691
940
|
Traits can be used as implicit attributes:
|
692
941
|
|
693
942
|
```ruby
|
@@ -701,6 +950,8 @@ end
|
|
701
950
|
Note that defining traits as implicit attributes will not work if you have a
|
702
951
|
factory or sequence with the same name as the trait.
|
703
952
|
|
953
|
+
### Attribute precedence
|
954
|
+
|
704
955
|
Traits that define the same attributes won't raise AttributeDefinitionErrors;
|
705
956
|
the trait that defines the attribute latest gets precedence.
|
706
957
|
|
@@ -731,7 +982,9 @@ factory :user do
|
|
731
982
|
end
|
732
983
|
```
|
733
984
|
|
734
|
-
|
985
|
+
### In child factories
|
986
|
+
|
987
|
+
You can override individual attributes granted by a trait in a child factory:
|
735
988
|
|
736
989
|
```ruby
|
737
990
|
factory :user do
|
@@ -751,7 +1004,10 @@ factory :user do
|
|
751
1004
|
end
|
752
1005
|
```
|
753
1006
|
|
754
|
-
|
1007
|
+
### Using traits
|
1008
|
+
|
1009
|
+
Traits can also be passed in as a list of symbols when you construct an instance
|
1010
|
+
from factory\_bot.
|
755
1011
|
|
756
1012
|
```ruby
|
757
1013
|
factory :user do
|
@@ -790,6 +1046,8 @@ end
|
|
790
1046
|
create_list(:user, 3, :admin, :male, name: "Jon Snow")
|
791
1047
|
```
|
792
1048
|
|
1049
|
+
### With associations
|
1050
|
+
|
793
1051
|
Traits can be used with associations easily too:
|
794
1052
|
|
795
1053
|
```ruby
|
@@ -830,6 +1088,8 @@ end
|
|
830
1088
|
create(:post).author
|
831
1089
|
```
|
832
1090
|
|
1091
|
+
### Traits within traits
|
1092
|
+
|
833
1093
|
Traits can be used within other traits to mix in their attributes.
|
834
1094
|
|
835
1095
|
```ruby
|
@@ -845,6 +1105,8 @@ factory :order do
|
|
845
1105
|
end
|
846
1106
|
```
|
847
1107
|
|
1108
|
+
### With transient attributes
|
1109
|
+
|
848
1110
|
Finally, traits can accept transient attributes.
|
849
1111
|
|
850
1112
|
```ruby
|
@@ -863,9 +1125,103 @@ end
|
|
863
1125
|
create :invoice, :with_amount, amount: 2
|
864
1126
|
```
|
865
1127
|
|
1128
|
+
### Enum traits
|
1129
|
+
|
1130
|
+
Given an Active Record model with an enum attribute:
|
1131
|
+
|
1132
|
+
```rb
|
1133
|
+
class Task < ActiveRecord::Base
|
1134
|
+
enum status: {queued: 0, started: 1, finished: 2}
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
```
|
1138
|
+
|
1139
|
+
factory\_bot will automatically define traits for each possible value of the
|
1140
|
+
enum:
|
1141
|
+
|
1142
|
+
```rb
|
1143
|
+
FactoryBot.define do
|
1144
|
+
factory :task
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
FactoryBot.build(:task, :queued)
|
1148
|
+
FactoryBot.build(:task, :started)
|
1149
|
+
FactoryBot.build(:task, :finished)
|
1150
|
+
```
|
1151
|
+
|
1152
|
+
Writing the traits out manually would be cumbersome, and is not necessary:
|
1153
|
+
|
1154
|
+
```rb
|
1155
|
+
FactoryBot.define do
|
1156
|
+
factory :task do
|
1157
|
+
trait :queued do
|
1158
|
+
status { :queued }
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
trait :started do
|
1162
|
+
status { :started }
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
trait :finished do
|
1166
|
+
status { :finished }
|
1167
|
+
end
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
```
|
1171
|
+
|
1172
|
+
If automatically defining traits for enum attributes on every factory is not
|
1173
|
+
desired, it is possible to disable the feature by setting
|
1174
|
+
`FactoryBot.automatically_define_enum_traits = false`
|
1175
|
+
|
1176
|
+
In that case, it is still possible to explicitly define traits for an enum
|
1177
|
+
attribute in a particular factory:
|
1178
|
+
|
1179
|
+
```rb
|
1180
|
+
FactoryBot.automatically_define_enum_traits = false
|
1181
|
+
|
1182
|
+
FactoryBot.define do
|
1183
|
+
factory :task do
|
1184
|
+
traits_for_enum(:status)
|
1185
|
+
end
|
1186
|
+
end
|
1187
|
+
```
|
1188
|
+
|
1189
|
+
It is also possible to use this feature for other enumerable values, not
|
1190
|
+
specifically tied to Active Record enum attributes.
|
1191
|
+
|
1192
|
+
With an array:
|
1193
|
+
|
1194
|
+
```rb
|
1195
|
+
class Task
|
1196
|
+
attr_accessor :status
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
FactoryBot.define do
|
1200
|
+
factory :task do
|
1201
|
+
traits_for_enum(:status, ["queued", "started", "finished"])
|
1202
|
+
end
|
1203
|
+
end
|
1204
|
+
```
|
1205
|
+
|
1206
|
+
Or with a hash:
|
1207
|
+
|
1208
|
+
```rb
|
1209
|
+
class Task
|
1210
|
+
attr_accessor :status
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
FactoryBot.define do
|
1214
|
+
factory :task do
|
1215
|
+
traits_for_enum(:status, { queued: 0, started: 1, finished: 2 })
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
```
|
1219
|
+
|
866
1220
|
Callbacks
|
867
1221
|
---------
|
868
1222
|
|
1223
|
+
### Default callbacks
|
1224
|
+
|
869
1225
|
factory\_bot makes available four callbacks for injecting some code:
|
870
1226
|
|
871
1227
|
* after(:build) - called after a factory is built (via `FactoryBot.build`, `FactoryBot.create`)
|
@@ -884,6 +1240,8 @@ end
|
|
884
1240
|
|
885
1241
|
Note that you'll have an instance of the user in the block. This can be useful.
|
886
1242
|
|
1243
|
+
### Multiple callbacks
|
1244
|
+
|
887
1245
|
You can also define multiple types of callbacks on the same factory:
|
888
1246
|
|
889
1247
|
```ruby
|
@@ -893,7 +1251,8 @@ factory :user do
|
|
893
1251
|
end
|
894
1252
|
```
|
895
1253
|
|
896
|
-
Factories can also define any number of the same kind of callback. These
|
1254
|
+
Factories can also define any number of the same kind of callback. These
|
1255
|
+
callbacks will be executed in the order they are specified:
|
897
1256
|
|
898
1257
|
```ruby
|
899
1258
|
factory :user do
|
@@ -904,9 +1263,12 @@ end
|
|
904
1263
|
|
905
1264
|
Calling `create` will invoke both `after_build` and `after_create` callbacks.
|
906
1265
|
|
907
|
-
Also, like standard attributes, child factories will inherit (and can also
|
1266
|
+
Also, like standard attributes, child factories will inherit (and can also
|
1267
|
+
define) callbacks from their parent factory.
|
908
1268
|
|
909
|
-
Multiple callbacks can be assigned to run a block; this is useful when building
|
1269
|
+
Multiple callbacks can be assigned to run a block; this is useful when building
|
1270
|
+
various strategies that run the same code (since there are no callbacks that are
|
1271
|
+
shared across all strategies).
|
910
1272
|
|
911
1273
|
```ruby
|
912
1274
|
factory :user do
|
@@ -916,6 +1278,8 @@ factory :user do
|
|
916
1278
|
end
|
917
1279
|
```
|
918
1280
|
|
1281
|
+
### Global callbacks
|
1282
|
+
|
919
1283
|
To override callbacks for all factories, define them within the
|
920
1284
|
`FactoryBot.define` block:
|
921
1285
|
|
@@ -930,7 +1294,9 @@ FactoryBot.define do
|
|
930
1294
|
end
|
931
1295
|
```
|
932
1296
|
|
933
|
-
|
1297
|
+
### Symbol#to_proc
|
1298
|
+
|
1299
|
+
You can call callbacks that rely on `Symbol#to_proc`:
|
934
1300
|
|
935
1301
|
```ruby
|
936
1302
|
# app/models/user.rb
|
@@ -953,15 +1319,16 @@ create(:user) # creates the user and confirms it
|
|
953
1319
|
Modifying factories
|
954
1320
|
-------------------
|
955
1321
|
|
956
|
-
If you're given a set of factories (say, from a gem developer) but want to
|
957
|
-
|
1322
|
+
If you're given a set of factories (say, from a gem developer) but want to
|
1323
|
+
change them to fit into your application better, you can modify that factory
|
1324
|
+
instead of creating a child factory and adding attributes there.
|
958
1325
|
|
959
1326
|
If a gem were to give you a User factory:
|
960
1327
|
|
961
1328
|
```ruby
|
962
1329
|
FactoryBot.define do
|
963
1330
|
factory :user do
|
964
|
-
full_name "John Doe"
|
1331
|
+
full_name { "John Doe" }
|
965
1332
|
sequence(:username) { |n| "user#{n}" }
|
966
1333
|
password { "password" }
|
967
1334
|
end
|
@@ -1018,6 +1385,14 @@ To set the attributes for each of the factories, you can pass in a hash as you n
|
|
1018
1385
|
twenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)
|
1019
1386
|
```
|
1020
1387
|
|
1388
|
+
In order to set different attributes for each factory, these methods may be passed a block, with the factory and the index as parameters:
|
1389
|
+
|
1390
|
+
```ruby
|
1391
|
+
twenty_somethings = build_list(:user, 10) do |user, i|
|
1392
|
+
user.date_of_birth = (20 + i).years.ago
|
1393
|
+
end
|
1394
|
+
```
|
1395
|
+
|
1021
1396
|
`build_stubbed_list` will give you fully stubbed out instances:
|
1022
1397
|
|
1023
1398
|
```ruby
|
@@ -1040,7 +1415,7 @@ users_attrs = attributes_for_list(:user, 25) # array of attribute hashes
|
|
1040
1415
|
Linting Factories
|
1041
1416
|
-----------------
|
1042
1417
|
|
1043
|
-
|
1418
|
+
factory\_bot allows for linting known factories:
|
1044
1419
|
|
1045
1420
|
```ruby
|
1046
1421
|
FactoryBot.lint
|
@@ -1067,9 +1442,10 @@ namespace :factory_bot do
|
|
1067
1442
|
desc "Verify that all FactoryBot factories are valid"
|
1068
1443
|
task lint: :environment do
|
1069
1444
|
if Rails.env.test?
|
1070
|
-
|
1071
|
-
|
1445
|
+
conn = ActiveRecord::Base.connection
|
1446
|
+
conn.transaction do
|
1072
1447
|
FactoryBot.lint
|
1448
|
+
raise ActiveRecord::Rollback
|
1073
1449
|
end
|
1074
1450
|
else
|
1075
1451
|
system("bundle exec rake factory_bot:lint RAILS_ENV='test'")
|
@@ -1081,8 +1457,7 @@ end
|
|
1081
1457
|
|
1082
1458
|
After calling `FactoryBot.lint`, you'll likely want to clear out the
|
1083
1459
|
database, as records will most likely be created. The provided example above
|
1084
|
-
uses
|
1085
|
-
gem to your Gemfile under the appropriate groups.
|
1460
|
+
uses an sql transaction and rollback to leave the database clean.
|
1086
1461
|
|
1087
1462
|
You can lint factories selectively by passing only factories you want linted:
|
1088
1463
|
|
@@ -1126,7 +1501,7 @@ FactoryBot.lint verbose: true
|
|
1126
1501
|
Custom Construction
|
1127
1502
|
-------------------
|
1128
1503
|
|
1129
|
-
If you want to use
|
1504
|
+
If you want to use factory\_bot to construct an object where some attributes
|
1130
1505
|
are passed to `initialize` or if you want to do something other than simply
|
1131
1506
|
calling `new` on your build class, you can override the default behavior by
|
1132
1507
|
defining `initialize_with` on your factory. Example:
|
@@ -1154,7 +1529,7 @@ end
|
|
1154
1529
|
build(:user).name # Jane Doe
|
1155
1530
|
```
|
1156
1531
|
|
1157
|
-
Although
|
1532
|
+
Although factory\_bot is written to work with ActiveRecord out of the box, it
|
1158
1533
|
can also work with any Ruby class. For maximum compatibility with ActiveRecord,
|
1159
1534
|
the default initializer builds all instances by calling `new` on your build class
|
1160
1535
|
without any arguments. It then calls attribute writer methods to assign all the
|
@@ -1165,7 +1540,7 @@ You can override the initializer in order to:
|
|
1165
1540
|
|
1166
1541
|
* Build non-ActiveRecord objects that require arguments to `initialize`
|
1167
1542
|
* Use a method other than `new` to instantiate the instance
|
1168
|
-
* Do
|
1543
|
+
* Do wild things like decorate the instance after it's built
|
1169
1544
|
|
1170
1545
|
When using `initialize_with`, you don't have to declare the class itself when
|
1171
1546
|
calling `new`; however, any other class methods you want to call will have to
|
@@ -1227,7 +1602,7 @@ build(:user)
|
|
1227
1602
|
User.new('value')
|
1228
1603
|
```
|
1229
1604
|
|
1230
|
-
This prevents duplicate assignment; in versions of
|
1605
|
+
This prevents duplicate assignment; in versions of factory\_bot before 4.0, it
|
1231
1606
|
would run this:
|
1232
1607
|
|
1233
1608
|
```ruby
|
@@ -1413,12 +1788,12 @@ with associations, as below:
|
|
1413
1788
|
|
1414
1789
|
```ruby
|
1415
1790
|
FactoryBot.define do
|
1416
|
-
factory :united_states, class: Location do
|
1791
|
+
factory :united_states, class: "Location" do
|
1417
1792
|
name { 'United States' }
|
1418
1793
|
association :location_group, factory: :north_america
|
1419
1794
|
end
|
1420
1795
|
|
1421
|
-
factory :north_america, class: LocationGroup do
|
1796
|
+
factory :north_america, class: "LocationGroup" do
|
1422
1797
|
name { 'North America' }
|
1423
1798
|
end
|
1424
1799
|
end
|