Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 247 lines (176 sloc) 7.528 kb
3acd41d @jferris Extract examples out to a different file so that the readme people se…
jferris authored
1 Getting Started
2 ===============
3
4 Defining factories
5 ------------------
6
7 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:
8
9 # This will guess the User class
10 FactoryGirl.define do
11 factory :user do
12 first_name 'John'
13 last_name 'Doe'
14 admin false
15 end
16
17 # This will use the User class (Admin would have been guessed)
18 factory :admin, :class => User do
19 first_name 'Admin'
20 last_name 'User'
21 admin true
22 end
23
24 # The same, but using a string instead of class constant
25 factory :admin, :class => 'user' do
26 first_name 'Admin'
27 last_name 'User'
28 admin true
29 end
30 end
31
32 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.
33
34 Attempting to define multiple factories with the same name will raise an error.
35
36 Factories can be defined anywhere, but will be automatically loaded if they
37 are defined in files at the following locations:
38
39 test/factories.rb
40 spec/factories.rb
41 test/factories/*.rb
42 spec/factories/*.rb
43
44 Using factories
45 ---------------
46
47 factory_girl supports several different build strategies: build, create, attributes_for and stub:
48
49 # Returns a User instance that's not saved
50 user = FactoryGirl.build(:user)
51
52 # Returns a saved User instance
53 user = FactoryGirl.create(:user)
54
55 # Returns a hash of attributes that can be used to build a User instance:
56 attrs = FactoryGirl.attributes_for(:user)
57
58 # Returns an object with all defined attributes stubbed out:
59 stub = FactoryGirl.stub(:user)
60
61 No matter which strategy is used, it's possible to override the defined attributes by passing a hash:
62
63 # Build a User instance and override the first_name property
64 user = FactoryGirl.build(:user, :first_name => 'Joe')
65 user.first_name
66 # => "Joe"
67
68 If repeating "FactoryGirl" is too verbose for you, you can mix the syntax methods in:
69
70 # rspec
71 RSpec.configure do |config|
72 config.include Factory::Syntax::Methods
73 end
74
75 # Test::Unit
76 class Test::Unit::TestCase
77 include Factory::Syntax::Methods
78 end
79
80 Lazy Attributes
81 ---------------
82
83 Most factory attributes can be added using static values that are evaluated when the factory is defined, but some attributes (such as associations and other attributes that must be dynamically generated) will need values assigned each time an instance is generated. These "lazy" attributes can be added by passing a block instead of a parameter:
84
85 factory :user do
86 # ...
87 activation_code { User.generate_activation_code }
88 end
89
90 Dependent Attributes
91 --------------------
92
93 Attributes can be based on the values of other attributes using the proxy that is yielded to lazy attribute blocks:
94
95 factory :user do
96 first_name 'Joe'
97 last_name 'Blow'
98 email { "#{first_name}.#{last_name}@example.com".downcase }
99 end
100
101 FactoryGirl.create(:user, :last_name => 'Doe').email
102 # => "joe.doe@example.com"
103
104 Associations
105 ------------
106
107 Associated instances can be generated by using the association method when
108 defining a lazy attribute:
109
110 factory :post do
111 # ...
112 author
113 end
114
115 You can also specify a different factory or override attributes:
116
117 factory :post do
118 # ...
119 association :author, :factory => :user, :last_name => 'Writely'
120 end
121
122 The behavior of the association method varies depending on the build strategy used for the parent object.
123
124 # Builds and saves a User and a Post
125 post = FactoryGirl.create(:post)
126 post.new_record? # => false
127 post.author.new_record # => false
128
129 # Builds and saves a User, and then builds but does not save a Post
130 post = FactoryGirl.build(:post)
131 post.new_record? # => true
132 post.author.new_record # => false
133
134 If the factory name is the same as the association name, the factory name can
135 be left out.
136
137 Inheritance
138 -----------
139
140 You can easily create multiple factories for the same class without repeating common attributes by using inheritance:
141
142 factory :post do
143 # the 'title' attribute is required for all posts
144 title 'A title'
145 end
146
147 factory :approved_post, :parent => :post do
148 approved true
149 # the 'approver' association is required for an approved post
150 association :approver, :factory => :user
151 end
152
153 Sequences
154 ---------
155
156 Unique values in a specific format (for example, e-mail addresses) can be
157 generated using sequences. Sequences are defined by calling sequence in a
158 definition block, and values in a sequence are generated by calling
159 Factory.next:
160
161 # Defines a new sequence
162 FactoryGirl.define do
163 sequence :email do |n|
164 "person#{n}@example.com"
165 end
166 end
167
168 Factory.next :email
169 # => "person1@example.com"
170
171 Factory.next :email
172 # => "person2@example.com"
173
174 Sequences can be used as attributes:
175
176 factory :user do
177 email
178 end
179
180 Or in lazy attributes:
181
182 factory :invite do
183 invitee { Factory.next(:email) }
184 end
185
186 And it's also possible to define an in-line sequence that is only used in
187 a particular factory:
188
189 factory :user do
190 sequence(:email) {|n| "person#{n}@example.com" }
191 end
192
193 Callbacks
194 ---------
195
196 Factory_girl makes available three callbacks for injecting some code:
197
198 * after_build - called after a factory is built (via FactoryGirl.build)
199 * after_create - called after a factory is saved (via FactoryGirl.create)
200 * after_stub - called after a factory is stubbed (via FactoryGirl.stub)
201
202 Examples:
203
204 # Define a factory that calls the generate_hashed_password method after it is built
205 factory :user do
206 after_build { |user| generate_hashed_password(user) }
207 end
208
209 Note that you'll have an instance of the user in the block. This can be useful.
210
211 You can also define multiple types of callbacks on the same factory:
212
213 factory :user do
214 after_build { |user| do_something_to(user) }
215 after_create { |user| do_something_else_to(user) }
216 end
217
218 Factories can also define any number of the same kind of callback. These callbacks will be executed in the order they are specified:
219
220 factory :user do
221 after_create { this_runs_first }
222 after_create { then_this }
223 end
224
225 Calling FactoryGirl.create will invoke both after_build and after_create callbacks.
226
227 Also, like standard attributes, child factories will inherit (and can also define) callbacks from their parent factory.
228
229 Alternate Syntaxes
230 ------------------
231
232 Users' tastes for syntax vary dramatically, but most users are looking for a common feature set. Because of this factory_girl supports "syntax layers" which provide alternate interfaces. See Factory::Syntax for information about the various layers available. For example, the Machinist-style syntax is popular:
233
234 require 'factory_girl/syntax/blueprint'
235 require 'factory_girl/syntax/make'
236 require 'factory_girl/syntax/sham'
237
238 Sham.email {|n| "#{n}@example.com" }
239
240 User.blueprint do
241 name { 'Billy Bob' }
242 email { Sham.email }
243 end
244
245 User.make(:name => 'Johnny')
246
Something went wrong with that request. Please try again.