データを設定し、私は次のテストを持っています。 3つのブロックがあります。最初のものは他の2つとは異なりshoulda
を使用しません。RSpecの+ shoulda:
post :create, product: attrs
とbefore
ブロックを使用しない場合、最初のテストは期待通りに失敗します。しかし、そこにbefore
ブロックを置くと、最初のテストは失敗しますが、他の2つは失敗します。私は製品名に対して一意性の検証をしていますが、工場でシーケンスを使用しているので問題はありません。
どうすればよいですか? rspecとshouldaマッチャーが同時に存在する場合に、テスト用のデータを一般的にどのようにセットアップすればよいですか?
describe "when user logged in" do
before(:each) do
login_user #logged in user is available by calling @user
end
context "POST create" do
context "with valid attributes" do
let!(:profile) { create(:profile, user: @user) }
let!(:industry) { create(:industry) }
let!(:attrs) { attributes_for(:product, user_id: @user.id, industry_ids: [ industry.id ]).merge(
product_features_attributes: [attributes_for(:product_feature)],
product_competitions_attributes: [attributes_for(:product_competition)],
product_usecases_attributes: [attributes_for(:product_usecase)]
) }
it "saves the new product in the db" do
expect{ post :create, product: attrs }.to change{ Product.count }.by(1)
end
#If I don't use this the 2 tests below fail. If I use it, then the test above fails.
# before do
# post :create, product: attrs
# end
it { is_expected.to redirect_to product_path(Product.last) }
it { is_expected.to set_flash.to('Product got created!') }
end
end
end
工場
factory :product, class: Product do
#name { Faker::Commerce.product_name }
sequence(:name) { |n| "ABC_#{n}" }
company { Faker::Company.name }
website { 'https://example.com' }
oneliner { Faker::Lorem.sentence }
description { Faker::Lorem.paragraph }
user
end
異なるコンテキストブロックの使用を検討しましたか?これにより、前のブロックを別々にすることができます。 –
Petr、やったよ。私はちょうどいいやり方が何なのか分かりません。その上に、問題の根本を理解したいと思います。 –