Rails - лучшие практики для ассоциаций с FactoryBot - PullRequest
0 голосов
/ 13 апреля 2020

Я пишу тесты с FactoryBot и Rspe c для приложения rails, и я пытаюсь связать один и тот же экземпляр с другими. Схема выглядит следующим образом:

   #merchant.rb (Devise Model)
   has_one :store

   #store.rb
   has_many :products
   belongs_to :merchant

   #cart.rb
   belongs_to :user
   belongs_to :store
   has_many :cart_products

   #cart_product.rb
   belongs_to :cart
   belongs_to :product

В тестах я хочу создать два товара для одного магазина, а затем положить их sh в корзину. На моих фабриках у меня есть что-то похожее на это:

FactoryBot.define do
  factory :merchant do
    email { "merchant@test.com" }
    password  { "password" }
  end
end

FactoryBot.define do
  factory :store do
    merchant
    name { "Test Store" }
  end
end

FactoryBot.define do
  factory :product do
    store
    trait :pizza do
      name { "Pizza" }
    end
    trait :burger do 
      name { "Burger" }
    end
  end
end

FactoryBot.define do
  factory :cart do
    user
    store
  end
end


В моих тестах с Rspe c я хочу

  • Создать 2 продукта
  • Ящик одна корзина
  • Создать 2 cart_products

, но этот код не работает

it "test something" do
 create(:product, :pizza)
 create(:product, :burger)
 create(:cart)
 #create 2 cart_products for the same cart
end

Пицца создается, но для гамбургера я получаю ошибку Mail has already been taken потому что, когда он создает гамбургер, он пытается воссоздать другой магазин и другого продавца, связанного с магазином (с тем же адресом электронной почты предыдущего, и Devise блокирует его). То же самое происходит, если я просто создаю один продукт и корзину. При создании корзины он пытается воссоздать магазин.

Как я могу решить эту проблему? Как лучше использовать один и тот же экземпляр (магазин) и передавать его 2 товарам и одной корзине?

Я нашел два решения онлайн, но я не уверен, что это хорошие подходы:

A)

it "test something" do
  user = create(:user)    
  store = create(:store)
  pizza = create(:product, :pizza, store: store)
  burger = create(:product, :burger, store: store)
  cart = create(:cart, user: user, store: store)
end

B)

#In the factories

FactoryBot.define do
  factory :product do
    store { Store.first || create(:store) }
    trait :pizza do
      name { "Pizza" }
    end
    trait :burger do 
      name { "Burger" }
    end
  end
end

FactoryBot.define do
  factory :cart do
    user
    store { Store.first || create(:store) }
  end
end

#in the test
it "test something" do
 create(:product, :pizza)
 create(:product, :burger)
 create(:cart)
 #create 2 cart_products for the same cart
end

Большое спасибо:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...