public
Description: Fixture replacement for focused and readable tests.
Homepage: http://thoughtbot.com/projects/factory_girl
Clone URL: git://github.com/thoughtbot/factory_girl.git
factory_girl / README.rdoc
deeed519 » jferris 2009-02-17 Updated and improved the do... 1 = factory_girl
2
964dd5e2 » qrush 2009-06-04 Fixing some spelling issues... 3 factory_girl is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance.
deeed519 » jferris 2009-02-17 Updated and improved the do... 4
5 == Download
6
7 Github: http://github.com/thoughtbot/factory_girl/tree/master
8
9 Gem:
10 gem install thoughtbot-factory_girl --source http://gems.github.com
11
12 Note: if you install factory_girl using the gem from Github, you'll need this
13 in your environment.rb if you want to use Rails 2.1+'s dependency manager:
14
15 config.gem "thoughtbot-factory_girl",
16 :lib => "factory_girl",
17 :source => "http://gems.github.com"
18
19 == Defining factories
20
964dd5e2 » qrush 2009-06-04 Fixing some spelling issues... 21 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:
deeed519 » jferris 2009-02-17 Updated and improved the do... 22
23 # This will guess the User class
24 Factory.define :user do |u|
25 u.first_name 'John'
26 u.last_name 'Doe'
27 u.admin false
28 end
29
30 # This will use the User class (Admin would have been guessed)
31 Factory.define :admin, :class => User do |u|
32 u.first_name 'Admin'
33 u.last_name 'User'
34 u.admin true
35 end
36
37 # The same, but using a string instead of class constant
38 Factory.define :admin, :class => 'user' do |u|
39 u.first_name 'Admin'
40 u.last_name 'User'
41 u.admin true
42 end
43
964dd5e2 » qrush 2009-06-04 Fixing some spelling issues... 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.
deeed519 » jferris 2009-02-17 Updated and improved the do... 45
46 Factories can either be defined anywhere, but will automatically be loaded if they are defined in files at the following locations:
47
48 test/factories.rb
49 spec/factories.rb
50 test/factories/*.rb
51 spec/factories/*.rb
52
53 == Using factories
54
55 factory_girl supports several different build strategies: build, create, attributes_for and stub:
56
57 # Returns a User instance that's not saved
58 user = Factory.build(:user)
59
60 # Returns a saved User instance
61 user = Factory.create(:user)
62
63 # Returns a hash of attributes that can be used to build a User instance:
64 attrs = Factory.attributes_for(:user)
65
66 # Returns an object with all defined attributes stubbed out:
67 stub = Factory.stub(:user)
68
69 You can use the Factory method as a shortcut for the default build strategy:
70
71 # Same as Factory.create :user:
72 user = Factory(:user)
73
74 The default strategy can be overriden:
75
76 # Now same as Factory.build(:user)
77 Factory.define :user, :default_strategy => :build do |u|
78 ...
79 end
80
81 user = Factory(:user)
82
83 No matter which startegy is used, it's possible to override the defined attributes by passing a hash:
84
85 # Build a User instance and override the first_name property
86 user = Factory.build(:user, :first_name => 'Joe')
87 user.first_name
88 # => "Joe"
89
90 == Lazy Attributes
91
92 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:
93
94 Factory.define :user do |u|
95 # ...
96 u.activation_code { User.generate_activation_code }
97 end
98
99 == Dependent Attributes
100
101 Attributes can be based on the values of other attributes using the proxy that is yieled to lazy attribute blocks:
102
103 Factory.define :user do |u|
104 u.first_name 'Joe'
105 u.last_name 'Blow'
106 u.email {|a| "#{a.first_name}.#{a.last_name}@example.com".downcase }
107 end
108
109 Factory(:user, :last_name => 'Doe').email
110 # => "joe.doe@example.com"
111
112 == Associations
113
114 Associated instances can be generated by using the association method when
115 defining a lazy attribute:
116
117 Factory.define :post do |p|
118 # ...
119 p.author {|author| author.association(: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 = Factory(: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 Factory.build(:post)
131 post.new_record? # => true
132 post.author.new_record # => false
133
134 Because this pattern is so common, a prettier syntax is available for defining
135 associations:
136
137 # The following definitions are equivilent:
138 Factory.define :post do |p|
139 p.author {|a| a.association(:user) }
140 end
141
142 Factory.define :post do |p|
143 p.association :author, :factory => :user
144 end
145
146 If the factory name is the same as the association name, the factory name can
147 be left out.
148
149 == Inheritance
150
964dd5e2 » qrush 2009-06-04 Fixing some spelling issues... 151 You can easily create multiple factories for the same class without repeating common attributes by using inheritance:
deeed519 » jferris 2009-02-17 Updated and improved the do... 152
153 Factory.define :post do |p|
154 # the 'title' attribute is required for all posts
155 p.title 'A title'
156 end
157
158 Factory.define :approved_post, :parent => :post do |p|
159 p.approved true
160 # the 'approver' association is required for an approved post
161 p.association :approver, :factory => :user
162 end
163
164 == Sequences
165
166 Unique values in a specific format (for example, e-mail addresses) can be
167 generated using sequences. Sequences are defined by calling Factory.sequence,
168 and values in a sequence are generated by calling Factory.next:
169
170 # Defines a new sequence
171 Factory.sequence :email do |n|
172 "person#{n}@example.com"
173 end
174
175 Factory.next :email
176 # => "person1@example.com"
177
178 Factory.next :email
179 # => "person2@example.com"
180
181 Sequences can be used in lazy attributes:
182
183 Factory.define :user do |f|
184 f.email { Factory.next(:email) }
185 end
186
187 And it's also possible to define an in-line sequence that is only used in
188 a particular factory:
189
190 Factory.define :user do |f|
ab50abb5 » jferris 2009-02-19 Fixed a sequence example in... 191 f.sequence(:email) {|n| "person#{n}@example.com" }
deeed519 » jferris 2009-02-17 Updated and improved the do... 192 end
193
194 == Alternate Syntaxes
195
196 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.
197
198 == More Information
199
200 Our blog: http://giantrobots.thoughtbot.com
201
30960d3c » qrush 2009-06-01 Updating link to rdocs 202 factory_girl rdoc: http://rdoc.info/projects/thoughtbot/factory_girl
deeed519 » jferris 2009-02-17 Updated and improved the do... 203
204 Mailing list: http://groups.google.com/group/factory_girl
205
b92412a7 » qrush 2009-06-10 Updating readme and contrib... 206 factory_girl issues: http://github.com/thoughtbot/factory_girl/issues
deeed519 » jferris 2009-02-17 Updated and improved the do... 207
208 == Contributing
209
210 Please read the contribution guidelines before submitting patches or pull requests.
211
212 == Author
213
214 factory_girl was written by Joe Ferris with contributions from several authors, including:
215 * Alex Sharp
216 * Eugene Bolshakov
217 * Jon Yurek
218 * Josh Nichols
219 * Josh Owens
220
6aa594fc » jferris 2009-02-17 Added credits for the synta... 221 The syntax layers are derived from software written by the following authors:
222 * Pete Yandell
223 * Rick Bradley
224 * Yossef Mendelssohn
225
deeed519 » jferris 2009-02-17 Updated and improved the do... 226 Thanks to all members of thoughtbot for inspiration, ideas, and funding.
227
228 Copyright 2008-2009 Joe Ferris and thoughtbot[http://www.thoughtbot.com], inc.