web-dev-qa-db-fra.com

Comment spécifier l'association avec factory_bot?

Par exemple, j'ai deux modèles, un utilisateur et un poste. Un message appartient à un utilisateur et un utilisateur a plusieurs messages

#spec/factories/post.rb
FactoryBot.define do
  factory :post do
    user
    body Faker::Movie.quote
    posted_at "2018-04-03 13:33:05"
  end
end

#spec/factories/user.rb
FactoryBot.define do 
  factory :user do 
    first_name 'Jake'
  end
end

En utilisant Rspec dans un test, je veux faire ceci:

user = create(:user, first_name: 'Barry') #id 1
post = create(:post, user: user)

Je m'attendrais à ce que le user_id de la publication soit 1 mais il crée un autre utilisateur avant et le user_id est 2.

Comment pouvez-vous spécifier l'association lorsque vous créez l'objet avec factory_bot/factory_girl?

12
Jake McAllister

Vous devez utiliser les associations explicit au lieu de implicit:

#spec/factories/post.rb
FactoryBot.define do
  factory :post do
    association :user    # <<<--- here the change
    body Faker::Movie.quote
    posted_at "2018-04-03 13:33:05"
  end
end

#spec/factories/user.rb
FactoryBot.define do 
  factory :user do 
    first_name 'Jake'
  end
end

https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md

16
Fran Martinez

Une autre option consiste à utiliser #trait méthode au sein du parent.

FactoryBot.define do
  factory :post do
    user nil
    body Faker::Movie.quote
    posted_at "2018-04-03 13:33:05"
  end
end

FactoryBot.define do 
  factory :user do 
    first_name 'Jake'
  end

  trait :with_post do
    after(:create) do |user|
      create(:post, user_id: user.id)
    end
  end
end

FactoryBot.create(:user, :with_post)
1
andriy-baran

L'enregistrement partagé (comme le font les appareils) a causé certains comportements inattendus car il n'a pas isolé les enregistrements de test les uns des autres. Ce qui n'est pas bon en test.

FactoryBot est passé de celui-ci à la prise en charge des tests isolés (comme le fait Rspec)

Si vous pensez toujours que c'est bon, vous pouvez choisir:

  • ajustez Rails Fixtures en plus de FactoryBot
  • utilisez user { User.first || create(:user) }
  • utilisez user = post.user

(Souvent, j'utilise user = post.user Pour y parvenir)

0
itsnikolay