dimanche 24 avril 2016

rspec + shoulda: setting up data

I have the following test. There are three it blocks. The first one doesn't use shoulda unlike the other two.

If I don't use the before block with post :create, product: attrs then the first test fails as expected. But If I put the before block there then the first test fails, but the other two pass. I have a uniqueness validation on product name, but that shouldn't be the problem as I'm using sequence with factory.

What should I do? How should I generally setup the data for testing when there are rspec and shoulda matchers present at the same time?

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

factories

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

Aucun commentaire:

Enregistrer un commentaire