Я пишу тесты с 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
Большое спасибо:)