DEV Community

n350071πŸ‡―πŸ‡΅
n350071πŸ‡―πŸ‡΅

Posted on • Edited on

[RSpec] Factorybot transient & trait with argument

πŸ€” Situation

You want to make a user with a book that title is 'Ruby'.

 class User has_many: books end class Book belongs_to: user end 
Enter fullscreen mode Exit fullscreen mode

πŸ‘ Solution

  • trait: you can run the process
  • trait with arguments: It is DEPRECATED, we should use transient instead.
  • transient: you can define and pass arguments with the block
 FactoryBot.define do factory :user, class: User do trait :with_book transient do # πŸ¦„1. default value when you use :with_book trait # πŸ¦„2. Dont't assign just 'Agile'. see also: https://thoughtbot.com/blog/deprecating-static-attributes-in-factory_bot-4-11 title { 'Agile' } end after(:build) do |user, evaluator| user.book = FactoryBot.create(:book, title: evaluator.title) end end end factory :book, class Book do sequence(:title) { |n| "book no.#{n}" } # πŸ¦„ default value end end 
Enter fullscreen mode Exit fullscreen mode
 let!(:user) { create(:user, :with_book, title: 'Ruby') } 
Enter fullscreen mode Exit fullscreen mode

πŸ”— Parent Note

Top comments (2)

Collapse
 
mxdavis profile image
Malki Davis

Very helpful! Small thing -- there should be a do after trait :with_book

Collapse
 
samuelfaure profile image
Samuel-Zacharie FAURE

Thank you for this small snippet, it was quite useful!