PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/GETTING_STARTED.md

http://github.com/thoughtbot/factory_girl
Markdown | 1758 lines | 1333 code | 425 blank | 0 comment | 0 complexity | ba7af16658a050b7db15a47abdc78dff MD5 | raw file
  1. Getting Started
  2. ===============
  3. * [Setup](#setup)
  4. + [Update Your Gemfile](#update-your-gemfile)
  5. + [JRuby](#jruby)
  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. * [Traits](#traits)
  56. + [Defining traits](#defining-traits)
  57. + [As implicit attributes](#as-implicit-attributes-1)
  58. + [Attribute precedence](#attribute-precedence)
  59. + [In child factories](#in-child-factories)
  60. + [Using traits](#using-traits)
  61. + [With associations](#with-associations-1)
  62. + [Traits within traits](#traits-within-traits)
  63. + [With transient attributes](#with-transient-attributes)
  64. * [Callbacks](#callbacks)
  65. + [Default callbacks](#default-callbacks)
  66. + [Multiple callbacks](#multiple-callbacks)
  67. + [Global callbacks](#global-callbacks)
  68. + [Symbol#to_proc](#symbolto_proc)
  69. * [Modifying factories](#modifying-factories)
  70. * [Building or Creating Multiple Records](#building-or-creating-multiple-records)
  71. * [Linting Factories](#linting-factories)
  72. * [Custom Construction](#custom-construction)
  73. * [Custom Strategies](#custom-strategies)
  74. * [Custom Callbacks](#custom-callbacks)
  75. * [Custom Methods to Persist Objects](#custom-methods-to-persist-objects)
  76. * [ActiveSupport Instrumentation](#activesupport-instrumentation)
  77. * [Rails Preloaders and RSpec](#rails-preloaders-and-rspec)
  78. * [Using Without Bundler](#using-without-bundler)
  79. Setup
  80. -----
  81. ### Update Your Gemfile
  82. If you're using Rails:
  83. ```ruby
  84. gem "factory_bot_rails"
  85. ```
  86. If you're *not* using Rails:
  87. ```ruby
  88. gem "factory_bot"
  89. ```
  90. ### JRuby
  91. JRuby users: factory\_bot works with JRuby starting with 1.6.7.2 (latest stable,
  92. as per July 2012). JRuby has to be used in 1.9 mode, for that, use JRUBY_OPTS
  93. environment variable:
  94. ```bash
  95. export JRUBY_OPTS=--1.9
  96. ```
  97. Once your Gemfile is updated, you'll want to update your bundle.
  98. ### Configure your test suite
  99. #### RSpec
  100. If you're using Rails, add the following configuration to
  101. `spec/support/factory_bot.rb` and be sure to require that file in
  102. `rails_helper.rb`:
  103. ```ruby
  104. RSpec.configure do |config|
  105. config.include FactoryBot::Syntax::Methods
  106. end
  107. ```
  108. If you're *not* using Rails:
  109. ```ruby
  110. RSpec.configure do |config|
  111. config.include FactoryBot::Syntax::Methods
  112. config.before(:suite) do
  113. FactoryBot.find_definitions
  114. end
  115. end
  116. ```
  117. #### Test::Unit
  118. ```ruby
  119. class Test::Unit::TestCase
  120. include FactoryBot::Syntax::Methods
  121. end
  122. ```
  123. #### Cucumber
  124. ```ruby
  125. # env.rb (Rails example location - RAILS_ROOT/features/support/env.rb)
  126. World(FactoryBot::Syntax::Methods)
  127. ```
  128. #### Spinach
  129. ```ruby
  130. class Spinach::FeatureSteps
  131. include FactoryBot::Syntax::Methods
  132. end
  133. ```
  134. #### Minitest
  135. ```ruby
  136. class Minitest::Unit::TestCase
  137. include FactoryBot::Syntax::Methods
  138. end
  139. ```
  140. #### Minitest::Spec
  141. ```ruby
  142. class Minitest::Spec
  143. include FactoryBot::Syntax::Methods
  144. end
  145. ```
  146. #### minitest-rails
  147. ```ruby
  148. class ActiveSupport::TestCase
  149. include FactoryBot::Syntax::Methods
  150. end
  151. ```
  152. If you do not include `FactoryBot::Syntax::Methods` in your test suite, then all
  153. factory\_bot methods will need to be prefaced with `FactoryBot`.
  154. Defining factories
  155. ------------------
  156. ### Factory name and attributes
  157. Each factory has a name and a set of attributes. The name is used to guess the
  158. class of the object by default:
  159. ```ruby
  160. # This will guess the User class
  161. FactoryBot.define do
  162. factory :user do
  163. first_name { "John" }
  164. last_name { "Doe" }
  165. admin { false }
  166. end
  167. end
  168. ```
  169. ### Specifying the class explicitly
  170. It is also possible to explicitly specify the class:
  171. ```ruby
  172. # This will use the User class (otherwise Admin would have been guessed)
  173. factory :admin, class: User
  174. ```
  175. If the constant is not available
  176. (if you are using a Rails engine that waits to load models, for example),
  177. you can also pass a symbol or string,
  178. which factory\_bot will constantize later, once you start building objects:
  179. ```ruby
  180. # It's OK if Doorkeeper::AccessToken isn't loaded yet
  181. factory :access_token, class: "Doorkeeper::AccessToken"
  182. ```
  183. ### Hash attributes
  184. Because of the block syntax in Ruby, defining attributes as `Hash`es (for
  185. serialized/JSON columns, for example) requires two sets of curly brackets:
  186. ```ruby
  187. factory :program do
  188. configuration { { auto_resolve: false, auto_define: true } }
  189. end
  190. ```
  191. ### Best practices
  192. It is recommended that you have one factory for each class that provides
  193. the simplest set of attributes necessary to create an instance of that class. If
  194. you're creating ActiveRecord objects, that means that you should only provide
  195. attributes that are required through validations and that do not have defaults.
  196. Other factories can be created through inheritance to cover common scenarios for
  197. each class.
  198. Attempting to define multiple factories with the same name will raise an error.
  199. ### Definition file paths
  200. Factories can be defined anywhere, but will be automatically loaded after
  201. calling `FactoryBot.find_definitions` if factories are defined in files at the
  202. following locations:
  203. test/factories.rb
  204. spec/factories.rb
  205. test/factories/*.rb
  206. spec/factories/*.rb
  207. ### Static Attributes
  208. Static attributes (without a block) are no longer available in factory\_bot 5.
  209. You can read more about the decision to remove them in
  210. [this blog post](https://robots.thoughtbot.com/deprecating-static-attributes-in-factory_bot-4-11).
  211. Using factories
  212. ---------------
  213. ### Build strategies
  214. factory\_bot supports several different build strategies: build, create,
  215. attributes\_for and build\_stubbed:
  216. ```ruby
  217. # Returns a User instance that's not saved
  218. user = build(:user)
  219. # Returns a saved User instance
  220. user = create(:user)
  221. # Returns a hash of attributes that can be used to build a User instance
  222. attrs = attributes_for(:user)
  223. # Returns an object with all defined attributes stubbed out
  224. stub = build_stubbed(:user)
  225. # Passing a block to any of the methods above will yield the return object
  226. create(:user) do |user|
  227. user.posts.create(attributes_for(:post))
  228. end
  229. ```
  230. ### Attribute overrides
  231. No matter which strategy is used, it's possible to override the defined
  232. attributes by passing a hash:
  233. ```ruby
  234. # Build a User instance and override the first_name property
  235. user = build(:user, first_name: "Joe")
  236. user.first_name
  237. # => "Joe"
  238. ```
  239. ### `build_stubbed` and `Marshal.dump`
  240. Note that objects created with `build_stubbed` cannot be serialized with
  241. `Marshal.dump`, since factory\_bot defines singleton methods on these objects.
  242. Aliases
  243. -------
  244. factory\_bot allows you to define aliases to existing factories to make them
  245. easier to re-use. This could come in handy when, for example, your Post object
  246. has an author attribute that actually refers to an instance of a User class.
  247. While normally factory\_bot can infer the factory name from the association name,
  248. in this case it will look for an author factory in vain. So, alias your user
  249. factory so it can be used under alias names.
  250. ```ruby
  251. factory :user, aliases: [:author, :commenter] do
  252. first_name { "John" }
  253. last_name { "Doe" }
  254. date_of_birth { 18.years.ago }
  255. end
  256. factory :post do
  257. author
  258. # instead of
  259. # association :author, factory: :user
  260. title { "How to read a book effectively" }
  261. body { "There are five steps involved." }
  262. end
  263. factory :comment do
  264. commenter
  265. # instead of
  266. # association :commenter, factory: :user
  267. body { "Great article!" }
  268. end
  269. ```
  270. Dependent Attributes
  271. --------------------
  272. Attributes can be based on the values of other attributes using the evaluator
  273. that is yielded to dynamic attribute blocks:
  274. ```ruby
  275. factory :user do
  276. first_name { "Joe" }
  277. last_name { "Blow" }
  278. email { "#{first_name}.#{last_name}@example.com".downcase }
  279. end
  280. create(:user, last_name: "Doe").email
  281. # => "joe.doe@example.com"
  282. ```
  283. Transient Attributes
  284. --------------------
  285. ### With other attributes
  286. There may be times where your code can be DRYed up by passing in transient
  287. attributes to factories. You can access transient attributes within other
  288. attributes (see [Dependent Attributes](#dependent-attributes)):
  289. ```ruby
  290. factory :user do
  291. transient do
  292. rockstar { true }
  293. end
  294. name { "John Doe#{" - Rockstar" if rockstar}" }
  295. end
  296. create(:user).name
  297. #=> "John Doe - ROCKSTAR"
  298. create(:user, rockstar: false).name
  299. #=> "John Doe"
  300. ```
  301. ### With `attributes_for`
  302. Transient attributes will be ignored within attributes\_for and won't be set on
  303. the model, even if the attribute exists or you attempt to override it.
  304. ### With callbacks
  305. If you need to access the evaluator in a factory\_bot callback,
  306. you'll need to declare a second block argument (for the evaluator) and access
  307. transient attributes from there.
  308. ```ruby
  309. factory :user do
  310. transient do
  311. upcased { false }
  312. end
  313. name { "John Doe" }
  314. after(:create) do |user, evaluator|
  315. user.name.upcase! if evaluator.upcased
  316. end
  317. end
  318. create(:user).name
  319. #=> "John Doe"
  320. create(:user, upcased: true).name
  321. #=> "JOHN DOE"
  322. ```
  323. ### With associations
  324. Transient [associations](#associations) are not supported in factory\_bot.
  325. Associations within the transient block will be treated as regular,
  326. non-transient associations.
  327. If needed, you can generally work around this by building a factory within a
  328. transient attribute:
  329. ```ruby
  330. factory :post
  331. factory :user do
  332. transient do
  333. post { build(:post) }
  334. end
  335. end
  336. ```
  337. Method Name / Reserved Word Attributes
  338. -------------------------------
  339. If your attributes conflict with existing methods or reserved words (all methods in the [DefinitionProxy](https://github.com/thoughtbot/factory_bot/blob/master/lib/factory_bot/definition_proxy.rb) class) you can define them with `add_attribute`.
  340. ```ruby
  341. factory :dna do
  342. add_attribute(:sequence) { 'GATTACA' }
  343. end
  344. factory :payment do
  345. add_attribute(:method) { 'paypal' }
  346. end
  347. ```
  348. Inheritance
  349. -----------
  350. ### Nested factories
  351. You can easily create multiple factories for the same class without repeating
  352. common attributes by nesting factories:
  353. ```ruby
  354. factory :post do
  355. title { "A title" }
  356. factory :approved_post do
  357. approved { true }
  358. end
  359. end
  360. approved_post = create(:approved_post)
  361. approved_post.title # => "A title"
  362. approved_post.approved # => true
  363. ```
  364. ### Assigning parent explicitly
  365. You can also assign the parent explicitly:
  366. ```ruby
  367. factory :post do
  368. title { "A title" }
  369. end
  370. factory :approved_post, parent: :post do
  371. approved { true }
  372. end
  373. ```
  374. ### Best practices
  375. As mentioned above, it's good practice to define a basic factory for each class
  376. with only the attributes required to create it. Then, create more specific
  377. factories that inherit from this basic parent. Factory definitions are still
  378. code, so keep them DRY.
  379. Associations
  380. ------------
  381. ### Implicit definition
  382. It's possible to set up associations within factories. If the factory name is
  383. the same as the association name, the factory name can be left out.
  384. ```ruby
  385. factory :post do
  386. # ...
  387. author
  388. end
  389. ```
  390. ### Explicit definition
  391. You can define associations explicitly. This can be handy especially when
  392. [Overriding attributes](#overriding-attributes)
  393. ```ruby
  394. factory :post do
  395. # ...
  396. association :author
  397. end
  398. ```
  399. ### Specifying the factory
  400. You can specify a different factory (although [Aliases](#aliases) might also
  401. help you out here).
  402. Implicitly:
  403. ```ruby
  404. factory :post do
  405. # ...
  406. author factory: :user
  407. end
  408. ```
  409. Explicitly:
  410. ```ruby
  411. factory :post do
  412. # ...
  413. association :author, factory: :user
  414. end
  415. ```
  416. ### Overriding attributes
  417. You can also override attributes.
  418. Implicitly:
  419. ```ruby
  420. factory :post do
  421. # ...
  422. author factory: :author, last_name: "Writely"
  423. end
  424. ```
  425. Explicitly:
  426. ```ruby
  427. factory :post do
  428. # ...
  429. association :author, last_name: "Writely"
  430. end
  431. ```
  432. ### Build strategies
  433. In factory\_bot 5, associations default to using the same build strategy as
  434. their parent object:
  435. ```ruby
  436. FactoryBot.define do
  437. factory :author
  438. factory :post do
  439. author
  440. end
  441. end
  442. post = build(:post)
  443. post.new_record? # => true
  444. post.author.new_record? # => true
  445. post = create(:post)
  446. post.new_record? # => false
  447. post.author.new_record? # => false
  448. ```
  449. This is different than the default behavior for previous versions of
  450. factory\_bot, where the association strategy would not always match the strategy
  451. of the parent object. If you want to continue using the old behavior, you can
  452. set the `use_parent_strategy` configuration option to `false`.
  453. ```ruby
  454. FactoryBot.use_parent_strategy = false
  455. # Builds and saves a User and a Post
  456. post = create(:post)
  457. post.new_record? # => false
  458. post.author.new_record? # => false
  459. # Builds and saves a User, and then builds but does not save a Post
  460. post = build(:post)
  461. post.new_record? # => true
  462. post.author.new_record? # => false
  463. ```
  464. To not save the associated object, specify `strategy: :build` in the factory:
  465. ```ruby
  466. FactoryBot.use_parent_strategy = false
  467. factory :post do
  468. # ...
  469. association :author, factory: :user, strategy: :build
  470. end
  471. # Builds a User, and then builds a Post, but does not save either
  472. post = build(:post)
  473. post.new_record? # => true
  474. post.author.new_record? # => true
  475. ```
  476. Please note that the `strategy: :build` option must be passed to an explicit call to `association`,
  477. and cannot be used with implicit associations:
  478. ```ruby
  479. factory :post do
  480. # ...
  481. author strategy: :build # <<< this does *not* work; causes author_id to be nil
  482. ```
  483. ### `has_many` associations
  484. Generating data for a `has_many` relationship is a bit more involved,
  485. depending on the amount of flexibility desired, but here's a surefire example
  486. of generating associated data.
  487. ```ruby
  488. FactoryBot.define do
  489. # post factory with a `belongs_to` association for the user
  490. factory :post do
  491. title { "Through the Looking Glass" }
  492. user
  493. end
  494. # user factory without associated posts
  495. factory :user do
  496. name { "John Doe" }
  497. # user_with_posts will create post data after the user has been created
  498. factory :user_with_posts do
  499. # posts_count is declared as a transient attribute and available in
  500. # attributes on the factory, as well as the callback via the evaluator
  501. transient do
  502. posts_count { 5 }
  503. end
  504. # the after(:create) yields two values; the user instance itself and the
  505. # evaluator, which stores all values from the factory, including transient
  506. # attributes; `create_list`'s second argument is the number of records
  507. # to create and we make sure the user is associated properly to the post
  508. after(:create) do |user, evaluator|
  509. create_list(:post, evaluator.posts_count, user: user)
  510. end
  511. end
  512. end
  513. end
  514. ```
  515. This allows us to do:
  516. ```ruby
  517. create(:user).posts.length # 0
  518. create(:user_with_posts).posts.length # 5
  519. create(:user_with_posts, posts_count: 15).posts.length # 15
  520. ```
  521. ### `has_and_belongs_to_many` associations
  522. Generating data for a `has_and_belongs_to_many` relationship is very similar
  523. to the above `has_many` relationship, with a small change, you need to pass an
  524. array of objects to the model's pluralized attribute name rather than a single
  525. object to the singular version of the attribute name.
  526. Here's an example with two models that are related via
  527. `has_and_belongs_to_many`:
  528. ```ruby
  529. FactoryBot.define do
  530. # language factory with a `belongs_to` association for the profile
  531. factory :language do
  532. title { "Through the Looking Glass" }
  533. profile
  534. end
  535. # profile factory without associated languages
  536. factory :profile do
  537. name { "John Doe" }
  538. # profile_with_languages will create language data after the profile has
  539. # been created
  540. factory :profile_with_languages do
  541. # languages_count is declared as an ignored attribute and available in
  542. # attributes on the factory, as well as the callback via the evaluator
  543. transient do
  544. languages_count { 5 }
  545. end
  546. # the after(:create) yields two values; the profile instance itself and
  547. # the evaluator, which stores all values from the factory, including
  548. # ignored attributes; `create_list`'s second argument is the number of
  549. # records to create and we make sure the profile is associated properly
  550. # to the language
  551. after(:create) do |profile, evaluator|
  552. create_list(:language, evaluator.languages_count, profiles: [profile])
  553. end
  554. end
  555. end
  556. end
  557. ```
  558. This allows us to do:
  559. ```ruby
  560. create(:profile).languages.length # 0
  561. create(:profile_with_languages).languages.length # 5
  562. create(:profile_with_languages, languages_count: 15).languages.length # 15
  563. ```
  564. ### Polymorphic associations
  565. Polymorphic associations can be handled with traits:
  566. ```ruby
  567. FactoryBot.define do
  568. factory :video
  569. factory :photo
  570. factory :comment do
  571. for_photo # default to the :for_photo trait if none is specified
  572. trait :for_video do
  573. association :commentable, factory: :video
  574. end
  575. trait :for_photo do
  576. association :commentable, factory: :photo
  577. end
  578. end
  579. end
  580. ```
  581. This allows us to do:
  582. ```ruby
  583. create(:comment)
  584. create(:comment, :for_video)
  585. create(:comment, :for_photo)
  586. ```
  587. Sequences
  588. ---------
  589. ### Global sequences
  590. Unique values in a specific format (for example, e-mail addresses) can be
  591. generated using sequences. Sequences are defined by calling `sequence` in a
  592. definition block, and values in a sequence are generated by calling
  593. `generate`:
  594. ```ruby
  595. # Defines a new sequence
  596. FactoryBot.define do
  597. sequence :email do |n|
  598. "person#{n}@example.com"
  599. end
  600. end
  601. generate :email
  602. # => "person1@example.com"
  603. generate :email
  604. # => "person2@example.com"
  605. ```
  606. ### With dynamic attributes
  607. Sequences can be used in dynamic attributes:
  608. ```ruby
  609. factory :invite do
  610. invitee { generate(:email) }
  611. end
  612. ```
  613. ### As implicit attributes
  614. Or as implicit attributes:
  615. ```ruby
  616. factory :user do
  617. email # Same as `email { generate(:email) }`
  618. end
  619. ```
  620. Note that defining sequences as implicit attributes will not work if you have a
  621. factory with the same name as the sequence.
  622. ### Inline sequences
  623. And it's also possible to define an in-line sequence that is only used in
  624. a particular factory:
  625. ```ruby
  626. factory :user do
  627. sequence(:email) { |n| "person#{n}@example.com" }
  628. end
  629. ```
  630. ### Initial value
  631. You can override the initial value. Any value that response to the `#next`
  632. method will work (e.g. 1, 2, 3, 'a', 'b', 'c')
  633. ```ruby
  634. factory :user do
  635. sequence(:email, 1000) { |n| "person#{n}@example.com" }
  636. end
  637. ```
  638. ### Without a block
  639. Without a block, the value will increment itself, starting at its initial value:
  640. ```ruby
  641. factory :post do
  642. sequence(:position)
  643. end
  644. ```
  645. ### Aliases
  646. Sequences can also have aliases. The sequence aliases share the same counter:
  647. ```ruby
  648. factory :user do
  649. sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
  650. end
  651. # will increase value counter for :email which is shared by :sender and :receiver
  652. generate(:sender)
  653. ```
  654. Define aliases and use default value (1) for the counter
  655. ```ruby
  656. factory :user do
  657. sequence(:email, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
  658. end
  659. ```
  660. Setting the value:
  661. ```ruby
  662. factory :user do
  663. sequence(:email, 'a', aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" }
  664. end
  665. ```
  666. The value just needs to support the `#next` method. Here the next value will be 'a', then 'b', etc.
  667. ### Rewinding
  668. Sequences can also be rewound with `FactoryBot.rewind_sequences`:
  669. ```ruby
  670. sequence(:email) {|n| "person#{n}@example.com" }
  671. generate(:email) # "person1@example.com"
  672. generate(:email) # "person2@example.com"
  673. generate(:email) # "person3@example.com"
  674. FactoryBot.rewind_sequences
  675. generate(:email) # "person1@example.com"
  676. ```
  677. This rewinds all registered sequences.
  678. Traits
  679. ------
  680. ### Defining traits
  681. Traits allow you to group attributes together and then apply them
  682. to any factory.
  683. ```ruby
  684. factory :user, aliases: [:author]
  685. factory :story do
  686. title { "My awesome story" }
  687. author
  688. trait :published do
  689. published { true }
  690. end
  691. trait :unpublished do
  692. published { false }
  693. end
  694. trait :week_long_publishing do
  695. start_at { 1.week.ago }
  696. end_at { Time.now }
  697. end
  698. trait :month_long_publishing do
  699. start_at { 1.month.ago }
  700. end_at { Time.now }
  701. end
  702. factory :week_long_published_story, traits: [:published, :week_long_publishing]
  703. factory :month_long_published_story, traits: [:published, :month_long_publishing]
  704. factory :week_long_unpublished_story, traits: [:unpublished, :week_long_publishing]
  705. factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing]
  706. end
  707. ```
  708. ### As implicit attributes
  709. Traits can be used as implicit attributes:
  710. ```ruby
  711. factory :week_long_published_story_with_title, parent: :story do
  712. published
  713. week_long_publishing
  714. title { "Publishing that was started at #{start_at}" }
  715. end
  716. ```
  717. Note that defining traits as implicit attributes will not work if you have a
  718. factory or sequence with the same name as the trait.
  719. ### Attribute precedence
  720. Traits that define the same attributes won't raise AttributeDefinitionErrors;
  721. the trait that defines the attribute latest gets precedence.
  722. ```ruby
  723. factory :user do
  724. name { "Friendly User" }
  725. login { name }
  726. trait :male do
  727. name { "John Doe" }
  728. gender { "Male" }
  729. login { "#{name} (M)" }
  730. end
  731. trait :female do
  732. name { "Jane Doe" }
  733. gender { "Female" }
  734. login { "#{name} (F)" }
  735. end
  736. trait :admin do
  737. admin { true }
  738. login { "admin-#{name}" }
  739. end
  740. factory :male_admin, traits: [:male, :admin] # login will be "admin-John Doe"
  741. factory :female_admin, traits: [:admin, :female] # login will be "Jane Doe (F)"
  742. end
  743. ```
  744. ### In child factories
  745. You can override individual attributes granted by a trait in a child factory:
  746. ```ruby
  747. factory :user do
  748. name { "Friendly User" }
  749. login { name }
  750. trait :male do
  751. name { "John Doe" }
  752. gender { "Male" }
  753. login { "#{name} (M)" }
  754. end
  755. factory :brandon do
  756. male
  757. name { "Brandon" }
  758. end
  759. end
  760. ```
  761. ### Using traits
  762. Traits can also be passed in as a list of symbols when you construct an instance
  763. from factory\_bot.
  764. ```ruby
  765. factory :user do
  766. name { "Friendly User" }
  767. trait :male do
  768. name { "John Doe" }
  769. gender { "Male" }
  770. end
  771. trait :admin do
  772. admin { true }
  773. end
  774. end
  775. # creates an admin user with gender "Male" and name "Jon Snow"
  776. create(:user, :admin, :male, name: "Jon Snow")
  777. ```
  778. This ability works with `build`, `build_stubbed`, `attributes_for`, and `create`.
  779. `create_list` and `build_list` methods are supported as well. Just remember to pass
  780. the number of instances to create/build as second parameter, as documented in the
  781. "Building or Creating Multiple Records" section of this file.
  782. ```ruby
  783. factory :user do
  784. name { "Friendly User" }
  785. trait :admin do
  786. admin { true }
  787. end
  788. end
  789. # creates 3 admin users with gender "Male" and name "Jon Snow"
  790. create_list(:user, 3, :admin, :male, name: "Jon Snow")
  791. ```
  792. ### With associations
  793. Traits can be used with associations easily too:
  794. ```ruby
  795. factory :user do
  796. name { "Friendly User" }
  797. trait :admin do
  798. admin { true }
  799. end
  800. end
  801. factory :post do
  802. association :user, :admin, name: 'John Doe'
  803. end
  804. # creates an admin user with name "John Doe"
  805. create(:post).user
  806. ```
  807. When you're using association names that're different than the factory:
  808. ```ruby
  809. factory :user do
  810. name { "Friendly User" }
  811. trait :admin do
  812. admin { true }
  813. end
  814. end
  815. factory :post do
  816. association :author, :admin, factory: :user, name: 'John Doe'
  817. # or
  818. association :author, factory: [:user, :admin], name: 'John Doe'
  819. end
  820. # creates an admin user with name "John Doe"
  821. create(:post).author
  822. ```
  823. ### Traits within traits
  824. Traits can be used within other traits to mix in their attributes.
  825. ```ruby
  826. factory :order do
  827. trait :completed do
  828. completed_at { 3.days.ago }
  829. end
  830. trait :refunded do
  831. completed
  832. refunded_at { 1.day.ago }
  833. end
  834. end
  835. ```
  836. ### With transient attributes
  837. Finally, traits can accept transient attributes.
  838. ```ruby
  839. factory :invoice do
  840. trait :with_amount do
  841. transient do
  842. amount { 1 }
  843. end
  844. after(:create) do |invoice, evaluator|
  845. create :line_item, invoice: invoice, amount: evaluator.amount
  846. end
  847. end
  848. end
  849. create :invoice, :with_amount, amount: 2
  850. ```
  851. Callbacks
  852. ---------
  853. ### Default callbacks
  854. factory\_bot makes available four callbacks for injecting some code:
  855. * after(:build) - called after a factory is built (via `FactoryBot.build`, `FactoryBot.create`)
  856. * before(:create) - called before a factory is saved (via `FactoryBot.create`)
  857. * after(:create) - called after a factory is saved (via `FactoryBot.create`)
  858. * after(:stub) - called after a factory is stubbed (via `FactoryBot.build_stubbed`)
  859. Examples:
  860. ```ruby
  861. # Define a factory that calls the generate_hashed_password method after it is built
  862. factory :user do
  863. after(:build) { |user| generate_hashed_password(user) }
  864. end
  865. ```
  866. Note that you'll have an instance of the user in the block. This can be useful.
  867. ### Multiple callbacks
  868. You can also define multiple types of callbacks on the same factory:
  869. ```ruby
  870. factory :user do
  871. after(:build) { |user| do_something_to(user) }
  872. after(:create) { |user| do_something_else_to(user) }
  873. end
  874. ```
  875. Factories can also define any number of the same kind of callback. These
  876. callbacks will be executed in the order they are specified:
  877. ```ruby
  878. factory :user do
  879. after(:create) { this_runs_first }
  880. after(:create) { then_this }
  881. end
  882. ```
  883. Calling `create` will invoke both `after_build` and `after_create` callbacks.
  884. Also, like standard attributes, child factories will inherit (and can also
  885. define) callbacks from their parent factory.
  886. Multiple callbacks can be assigned to run a block; this is useful when building
  887. various strategies that run the same code (since there are no callbacks that are
  888. shared across all strategies).
  889. ```ruby
  890. factory :user do
  891. callback(:after_stub, :before_create) { do_something }
  892. after(:stub, :create) { do_something_else }
  893. before(:create, :custom) { do_a_third_thing }
  894. end
  895. ```
  896. ### Global callbacks
  897. To override callbacks for all factories, define them within the
  898. `FactoryBot.define` block:
  899. ```ruby
  900. FactoryBot.define do
  901. after(:build) { |object| puts "Built #{object}" }
  902. after(:create) { |object| AuditLog.create(attrs: object.attributes) }
  903. factory :user do
  904. name { "John Doe" }
  905. end
  906. end
  907. ```
  908. ### Symbol#to_proc
  909. You can call callbacks that rely on `Symbol#to_proc`:
  910. ```ruby
  911. # app/models/user.rb
  912. class User < ActiveRecord::Base
  913. def confirm!
  914. # confirm the user account
  915. end
  916. end
  917. # spec/factories.rb
  918. FactoryBot.define do
  919. factory :user do
  920. after :create, &:confirm!
  921. end
  922. end
  923. create(:user) # creates the user and confirms it
  924. ```
  925. Modifying factories
  926. -------------------
  927. If you're given a set of factories (say, from a gem developer) but want to
  928. change them to fit into your application better, you can modify that factory
  929. instead of creating a child factory and adding attributes there.
  930. If a gem were to give you a User factory:
  931. ```ruby
  932. FactoryBot.define do
  933. factory :user do
  934. full_name { "John Doe" }
  935. sequence(:username) { |n| "user#{n}" }
  936. password { "password" }
  937. end
  938. end
  939. ```
  940. Instead of creating a child factory that added additional attributes:
  941. ```ruby
  942. FactoryBot.define do
  943. factory :application_user, parent: :user do
  944. full_name { "Jane Doe" }
  945. date_of_birth { 21.years.ago }
  946. gender { "Female" }
  947. health { 90 }
  948. end
  949. end
  950. ```
  951. You could modify that factory instead.
  952. ```ruby
  953. FactoryBot.modify do
  954. factory :user do
  955. full_name { "Jane Doe" }
  956. date_of_birth { 21.years.ago }
  957. gender { "Female" }
  958. health { 90 }
  959. end
  960. end
  961. ```
  962. When modifying a factory, you can change any of the attributes you want (aside from callbacks).
  963. `FactoryBot.modify` must be called outside of a `FactoryBot.define` block as it operates on factories differently.
  964. A caveat: you can only modify factories (not sequences or traits) and callbacks *still compound as they normally would*. So, if
  965. the factory you're modifying defines an `after(:create)` callback, you defining an `after(:create)` won't override it, it'll just get run after the first callback.
  966. Building or Creating Multiple Records
  967. -------------------------------------
  968. Sometimes, you'll want to create or build multiple instances of a factory at once.
  969. ```ruby
  970. built_users = build_list(:user, 25)
  971. created_users = create_list(:user, 25)
  972. ```
  973. These methods will build or create a specific amount of factories and return them as an array.
  974. To set the attributes for each of the factories, you can pass in a hash as you normally would.
  975. ```ruby
  976. twenty_year_olds = build_list(:user, 25, date_of_birth: 20.years.ago)
  977. ```
  978. In order to set different attributes for each factory, these methods may be passed a block, with the factory and the index as parameters:
  979. ```ruby
  980. twenty_somethings = build_list(:user, 10) do |user, i|
  981. user.date_of_birth = (20 + i).years.ago
  982. end
  983. ```
  984. `build_stubbed_list` will give you fully stubbed out instances:
  985. ```ruby
  986. stubbed_users = build_stubbed_list(:user, 25) # array of stubbed users
  987. ```
  988. There's also a set of `*_pair` methods for creating two records at a time:
  989. ```ruby
  990. built_users = build_pair(:user) # array of two built users
  991. created_users = create_pair(:user) # array of two created users
  992. ```
  993. If you need multiple attribute hashes, `attributes_for_list` will generate them:
  994. ```ruby
  995. users_attrs = attributes_for_list(:user, 25) # array of attribute hashes
  996. ```
  997. Linting Factories
  998. -----------------
  999. factory\_bot allows for linting known factories:
  1000. ```ruby
  1001. FactoryBot.lint
  1002. ```
  1003. `FactoryBot.lint` creates each factory and catches any exceptions raised
  1004. during the creation process. `FactoryBot::InvalidFactoryError` is raised with
  1005. a list of factories (and corresponding exceptions) for factories which could
  1006. not be created.
  1007. Recommended usage of `FactoryBot.lint`
  1008. is to run this in a task
  1009. before your test suite is executed.
  1010. Running it in a `before(:suite)`,
  1011. will negatively impact the performance
  1012. of your tests
  1013. when running single tests.
  1014. Example Rake task:
  1015. ```ruby
  1016. # lib/tasks/factory_bot.rake
  1017. namespace :factory_bot do
  1018. desc "Verify that all FactoryBot factories are valid"
  1019. task lint: :environment do
  1020. if Rails.env.test?
  1021. conn = ActiveRecord::Base.connection
  1022. conn.transaction do
  1023. FactoryBot.lint
  1024. raise ActiveRecord::Rollback
  1025. end
  1026. else
  1027. system("bundle exec rake factory_bot:lint RAILS_ENV='test'")
  1028. fail if $?.exitstatus.nonzero?
  1029. end
  1030. end
  1031. end
  1032. ```
  1033. After calling `FactoryBot.lint`, you'll likely want to clear out the
  1034. database, as records will most likely be created. The provided example above
  1035. uses an sql transaction and rollback to leave the database clean.
  1036. You can lint factories selectively by passing only factories you want linted:
  1037. ```ruby
  1038. factories_to_lint = FactoryBot.factories.reject do |factory|
  1039. factory.name =~ /^old_/
  1040. end
  1041. FactoryBot.lint factories_to_lint
  1042. ```
  1043. This would lint all factories that aren't prefixed with `old_`.
  1044. Traits can also be linted. This option verifies that each
  1045. and every trait of a factory generates a valid object on its own.
  1046. This is turned on by passing `traits: true` to the `lint` method:
  1047. ```ruby
  1048. FactoryBot.lint traits: true
  1049. ```
  1050. This can also be combined with other arguments:
  1051. ```ruby
  1052. FactoryBot.lint factories_to_lint, traits: true
  1053. ```
  1054. You can also specify the strategy used for linting:
  1055. ```ruby
  1056. FactoryBot.lint strategy: :build
  1057. ```
  1058. Verbose linting will include full backtraces for each error, which can be
  1059. helpful for debugging:
  1060. ```ruby
  1061. FactoryBot.lint verbose: true
  1062. ```
  1063. Custom Construction
  1064. -------------------
  1065. If you want to use factory\_bot to construct an object where some attributes
  1066. are passed to `initialize` or if you want to do something other than simply
  1067. calling `new` on your build class, you can override the default behavior by
  1068. defining `initialize_with` on your factory. Example:
  1069. ```ruby
  1070. # user.rb
  1071. class User
  1072. attr_accessor :name, :email
  1073. def initialize(name)
  1074. @name = name
  1075. end
  1076. end
  1077. # factories.rb
  1078. sequence(:email) { |n| "person#{n}@example.com" }
  1079. factory :user do
  1080. name { "Jane Doe" }
  1081. email
  1082. initialize_with { new(name) }
  1083. end
  1084. build(:user).name # Jane Doe
  1085. ```
  1086. Although factory\_bot is written to work with ActiveRecord out of the box, it
  1087. can also work with any Ruby class. For maximum compatibility with ActiveRecord,
  1088. the default initializer builds all instances by calling `new` on your build class
  1089. without any arguments. It then calls attribute writer methods to assign all the
  1090. attribute values. While that works fine for ActiveRecord, it actually doesn't
  1091. work for almost any other Ruby class.
  1092. You can override the initializer in order to:
  1093. * Build non-ActiveRecord objects that require arguments to `initialize`
  1094. * Use a method other than `new` to instantiate the instance
  1095. * Do wild things like decorate the instance after it's built
  1096. When using `initialize_with`, you don't have to declare the class itself when
  1097. calling `new`; however, any other class methods you want to call will have to
  1098. be called on the class explicitly.
  1099. For example:
  1100. ```ruby
  1101. factory :user do
  1102. name { "John Doe" }
  1103. initialize_with { User.build_with_name(name) }
  1104. end
  1105. ```
  1106. You can also access all public attributes within the `initialize_with` block
  1107. by calling `attributes`:
  1108. ```ruby
  1109. factory :user do
  1110. transient do
  1111. comments_count { 5 }
  1112. end
  1113. name "John Doe"
  1114. initialize_with { new(attributes) }
  1115. end
  1116. ```
  1117. This will build a hash of all attributes to be passed to `new`. It won't
  1118. include transient attributes, but everything else defined in the factory will be
  1119. passed (associations, evaluated sequences, etc.)
  1120. You can define `initialize_with` for all factories by including it in the
  1121. `FactoryBot.define` block:
  1122. ```ruby
  1123. FactoryBot.define do
  1124. initialize_with { new("Awesome first argument") }
  1125. end
  1126. ```
  1127. When using `initialize_with`, attributes accessed from within the `initialize_with`
  1128. block are assigned *only* in the constructor; this equates to roughly the
  1129. following code:
  1130. ```ruby
  1131. FactoryBot.define do
  1132. factory :user do
  1133. initialize_with { new(name) }
  1134. name { 'value' }
  1135. end
  1136. end
  1137. build(:user)
  1138. # runs
  1139. User.new('value')
  1140. ```
  1141. This prevents duplicate assignment; in versions of factory\_bot before 4.0, it
  1142. would run this:
  1143. ```ruby
  1144. FactoryBot.define do
  1145. factory :user do
  1146. initialize_with { new(name) }
  1147. name { 'value' }
  1148. end
  1149. end
  1150. build(:user)
  1151. # runs
  1152. user = User.new('value')
  1153. user.name = 'value'
  1154. ```
  1155. Custom Strategies
  1156. -----------------
  1157. There are times where you may want to extend behavior of factory\_bot by
  1158. adding a custom build strategy.
  1159. Strategies define two methods: `association` and `result`. `association`
  1160. receives a `FactoryBot::FactoryRunner` instance, upon which you can call
  1161. `run`, overriding the strategy if you want. The second method, `result`,
  1162. receives a `FactoryBot::Evaluation` instance. It provides a way to trigger
  1163. callbacks (with `notify`), `object` or `hash` (to get the result instance or a
  1164. hash based on the attributes defined in the factory), and `create`, which
  1165. executes the `to_create` callback defined on the factory.
  1166. To understand how factory\_bot uses strategies internally, it's probably
  1167. easiest to just view the source for each of the four default strategies.
  1168. Here's an example of composing a strategy using
  1169. `FactoryBot::Strategy::Create` to build a JSON representation of your model.
  1170. ```ruby
  1171. class JsonStrategy
  1172. def initialize
  1173. @strategy = FactoryBot.strategy_by_name(:create).new
  1174. end
  1175. delegate :association, to: :@strategy
  1176. def result(evaluation)
  1177. @strategy.result(evaluation).to_json
  1178. end
  1179. end
  1180. ```
  1181. For factory\_bot to recognize the new strategy, you can register it:
  1182. ```ruby
  1183. FactoryBot.register_strategy(:json, JsonStrategy)
  1184. ```
  1185. This allows you to call
  1186. ```ruby
  1187. FactoryBot.json(:user)
  1188. ```
  1189. Finally, you can override factory\_bot's own strategies if you'd like by
  1190. registering a new object in place of the strategies.
  1191. Custom Callbacks
  1192. ----------------
  1193. Custom callbacks can be defined if you're using custom strategies:
  1194. ```ruby
  1195. class JsonStrategy
  1196. def initialize
  1197. @strategy = FactoryBot.strategy_by_name(:create).new
  1198. end
  1199. delegate :association, to: :@strategy
  1200. def result(evaluation)
  1201. result = @strategy.result(evaluation)
  1202. evaluation.notify(:before_json, result)
  1203. result.to_json.tap do |json|
  1204. evaluation.notify(:after_json, json)
  1205. evaluation.notify(:make_json_awesome, json)
  1206. end
  1207. end
  1208. end
  1209. FactoryBot.register_strategy(:json, JsonStrategy)
  1210. FactoryBot.define do
  1211. factory :user do
  1212. before(:json) { |user| do_something_to(user) }
  1213. after(:json) { |user_json| do_something_to(user_json) }
  1214. callback(:make_json_awesome) { |user_json| do_something_to(user_json) }
  1215. end
  1216. end
  1217. ```
  1218. Custom Methods to Persist Objects
  1219. ---------------------------------
  1220. By default, creating a record will call `save!` on the instance; since this
  1221. may not always be ideal, you can override that behavior by defining
  1222. `to_create` on the factory:
  1223. ```ruby
  1224. factory :different_orm_model do
  1225. to_create { |instance| instance.persist! }
  1226. end
  1227. ```
  1228. To disable the persistence method altogether on create, you can `skip_create`
  1229. for that factory:
  1230. ```ruby
  1231. factory :user_without_database do
  1232. skip_create
  1233. end
  1234. ```
  1235. To override `to_create` for all factories, define it within the
  1236. `FactoryBot.define` block:
  1237. ```ruby
  1238. FactoryBot.define do
  1239. to_create { |instance| instance.persist! }
  1240. factory :user do
  1241. name { "John Doe" }
  1242. end
  1243. end
  1244. ```
  1245. ActiveSupport Instrumentation
  1246. -----------------------------
  1247. In order to track what factories are created (and with what build strategy),
  1248. `ActiveSupport::Notifications` are included to provide a way to subscribe to
  1249. factories being run. One example would be to track factories based on a
  1250. threshold of execution time.
  1251. ```ruby
  1252. ActiveSupport::Notifications.subscribe("factory_bot.run_factory") do |name, start, finish, id, payload|
  1253. execution_time_in_seconds = finish - start
  1254. if execution_time_in_seconds >= 0.5
  1255. $stderr.puts "Slow factory: #{payload[:name]} using strategy #{payload[:strategy]}"
  1256. end
  1257. end
  1258. ```
  1259. Another example would be tracking all factories and how they're used
  1260. throughout your test suite. If you're using RSpec, it's as simple as adding a
  1261. `before(:suite)` and `after(:suite)`:
  1262. ```ruby
  1263. factory_bot_results = {}
  1264. config.before(:suite) do
  1265. ActiveSupport::Notifications.subscribe("factory_bot.run_factory") do |name, start, finish, id, payload|
  1266. factory_name = payload[:name]
  1267. strategy_name = payload[:strategy]
  1268. factory_bot_results[factory_name] ||= {}
  1269. factory_bot_results[factory_name][strategy_name] ||= 0
  1270. factory_bot_results[factory_name][strategy_name] += 1
  1271. end
  1272. end
  1273. config.after(:suite) do
  1274. puts factory_bot_results
  1275. end
  1276. ```
  1277. Rails Preloaders and RSpec
  1278. --------------------------
  1279. When running RSpec with a Rails preloader such as `spring` or `zeus`, it's possible
  1280. to encounter an `ActiveRecord::AssociationTypeMismatch` error when creating a factory
  1281. with associations, as below:
  1282. ```ruby
  1283. FactoryBot.define do
  1284. factory :united_states, class: "Location" do
  1285. name { 'United States' }
  1286. association :location_group, factory: :north_america
  1287. end
  1288. factory :north_america, class: "LocationGroup" do
  1289. name { 'North America' }
  1290. end
  1291. end
  1292. ```
  1293. The error occurs during the run of the test suite:
  1294. ```
  1295. Failure/Error: united_states = create(:united_states)
  1296. ActiveRecord::AssociationTypeMismatch:
  1297. LocationGroup(#70251250797320) expected, got LocationGroup(#70251200725840)
  1298. ```
  1299. The two possible solutions are to either run the suite without the preloader, or
  1300. to add `FactoryBot.reload` to the RSpec configuration, like so:
  1301. ```ruby
  1302. RSpec.configure do |config|
  1303. config.before(:suite) { FactoryBot.reload }
  1304. end
  1305. ```
  1306. Using Without Bundler
  1307. ---------------------
  1308. If you're not using Bundler, be sure to have the gem installed and call:
  1309. ```ruby
  1310. require 'factory_bot'
  1311. ```
  1312. Once required, assuming you have a directory structure of `spec/factories` or
  1313. `test/factories`, all you'll need to do is run:
  1314. ```ruby
  1315. FactoryBot.find_definitions
  1316. ```
  1317. If you're using a separate directory structure for your factories, you can
  1318. change the definition file paths before trying to find definitions:
  1319. ```ruby
  1320. FactoryBot.definition_file_paths = %w(custom_factories_directory)
  1321. FactoryBot.find_definitions
  1322. ```
  1323. If you don't have a separate directory of factories and would like to define
  1324. them inline, that's possible as well:
  1325. ```ruby
  1326. require 'factory_bot'
  1327. FactoryBot.define do
  1328. factory :user do
  1329. name { 'John Doe' }
  1330. date_of_birth { 21.years.ago }
  1331. end
  1332. end
  1333. ```