OSDN Git Service

Regular updates
[twpd/master.git] / factory_bot.md
1 ---
2 title: Factory Bot
3 category: Ruby libraries
4 layout: 2017/sheet
5 weight: -3
6 updated: 2020-07-06
7 keywords:
8   - "FactoryBot.define do"
9   - "factory :user"
10   - "first_name 'John'"
11   - "sequence(:username) { |n| \"user#{n}\" }"
12 tags: [Featurable]
13 ---
14
15 ## Factories
16 {: .-three-column}
17
18 ### Introduction
19 {: .-intro}
20
21 [Factory Bot](http://www.rubydoc.info/gems/factory_bot/) is a helper for writing factories for Ruby tests. It was previously known as Factory Girl. For older versions, use `FactoryGirl` instead of `FactoryBot`.
22
23 - [Factory Bot documentation](http://www.rubydoc.info/gems/factory_bot/) _(rubydoc.info)_
24 - [Getting started](https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md) _(github.com)_
25 - [Source code](https://github.com/thoughtbot/factory_bot) _(github.com)_
26
27 ### Defining factories
28
29 ```ruby
30 FactoryBot.define do
31   factory :user do
32     first_name { 'John' }
33     last_name  { 'Doe' }
34     birthdate  { 21.years.ago }
35     admin { false }
36
37     sequence(:username) { |n| "user#{n}" }
38   end
39 end
40 ```
41 {: data-line="2"}
42
43 See: [Defining factories](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Defining_factories)
44
45 ### Extra options
46
47 #### Custom class names
48
49 ```ruby
50 factory :user, class: 'User' do
51   ···
52 end
53 ```
54
55 #### Aliases
56
57 ```ruby
58 factory :user, aliases: [:author] do
59   ···
60 end
61 ```
62
63 ### Using
64
65 #### Build a model
66
67 ```ruby
68 FactoryBot.build(:user)
69 ```
70
71 #### Other ways
72
73 ```ruby
74 build(:user)           # → model (not saved)
75 create(:user)          # → model (saved)
76 attributes_for(:user)  # → hash
77 build_stubbed(:user)   # stubbed out attributes
78 ```
79
80 #### With options
81
82 ```ruby
83 build(:user, name: 'John')
84 ```
85
86 #### Lists
87
88 ```ruby
89 create_list(:user, 3)
90 build_list(:user, 3)
91 ```
92
93 ## Associations
94
95 ### Defining
96
97 ```ruby
98 factory :post do
99   association :author, factory: :user
100   association :author, factory: [:user, :admin]
101 end
102 ```
103 {: data-line="2,3"}
104
105 #### or
106
107 ```ruby
108 factory :post do
109   author  # assumes there's a factory :author
110 end
111 ```
112
113 ### After-create hooks
114
115 ```ruby
116 factory :post do
117   after :create do |post|
118     create :theme, post: post             # has_one
119     create_list :comment, 3, post: post   # has_many
120   end
121 end
122 ```
123 {: data-line="2"}
124
125 ## Other features
126 {: .-three-column}
127
128 ### Traits
129
130 ```ruby
131 factory :user do
132   trait :admin do
133     admin { true }
134   end
135 end
136 ```
137 {: data-line="2,3,4"}
138
139 ```ruby
140 create :user, :admin
141 ```
142
143 Traits allow you to group attributes together.
144 See: [Traits](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Traits)
145
146 ### Nested factories
147
148 ```ruby
149 factory :user do
150   first_name { 'John' }
151
152   factory :sample_user do
153     first_name { FFaker::Name.first_name }
154   end
155 end
156 ```
157 {: data-line="4,5,6"}
158
159 ```ruby
160 create :sample_user
161 ```
162
163 See: [Inheritance](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Inheritance)
164
165 ### Sub-factories
166
167 ```ruby
168 factory :user do
169   ···
170 end
171 ```
172
173 ```ruby
174 factory :sample_user, parent: :user do
175   first_name { FFaker::Name.first_name }
176 end
177 ```
178 {: data-line="1"}
179
180 ```ruby
181 create :sample_user
182 ```
183
184 Works the same as nested factories.
185
186 ### Options (transients)
187
188 ```ruby
189 factory :user do
190   transient do
191     upcased { true }
192   end
193
194   after :create do |user, options|
195     user.name.upcase! if options.upcased
196   end
197 end
198 ```
199 {: data-line="2,3,4"}
200
201 ```ruby
202 create(user, upcased: true)
203 ```
204
205 Transient attributes will not get passed to the model, but will be available in after-create hooks.
206 See: [Transient attributes](http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md#Transient_Attributes)
207
208 ### Paths
209
210 * test/factories.rb
211 * spec/factories.rb
212 * test/factories/*.rb
213 * spec/factories/*.rb
214
215 Place your factories in these locations.
216 {: .-setup}
217
218 ## See also
219 {: .-one-column}
220
221 * <http://rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md>