rspec + shoulda:设置数据 [英] rspec + shoulda: setting up data

查看:57
本文介绍了rspec + shoulda:设置数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下测试.共有三个 it 块.与其他两个不同,第一个不使用 should.

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

如果我不将 before 块与 post :create, product: attrs 一起使用,那么第一个测试会按预期失败.但是如果我把 before 块放在那里,那么第一个测试失败,但其他两个通过.我对产品名称进行了唯一性验证,但这应该不是问题,因为我使用的是带有工厂的序列.

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.

我该怎么办?当同时存在 rspec 和 shoulda 匹配器时,我通常应该如何设置用于测试的数据?

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

工厂

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

推荐答案

你不能同时拥有它.如果你在 before 中执行你正在测试的方法,那么你不能再次执行它来查看它是否改变了 Product 计数.如果您之前没有执行它,那么您必须在您的示例中执行它,因此不能使用 is_expected 一种线性格式.

You can't have it both ways. If you execute the method you are testing in the before, then you can't execute it again to see if it changes the Product count. If you don't execute it in your before, then you must execute it in your example and therefore can't use the is_expected one liner format.

有多种选择.这是一个将方法的执行合并到所有示例中的示例.

There are a variety of alternatives. Here is one that incorporates the execution of the method into all the examples.

describe "when user logged in" do
  before(:each) do
    login_user #logged in user is available by calling @user
  end

  describe "POST create" do
    subject(:create) { post :create, product: attrs }
    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{ create }.to change{ Product.count }.by(1)
      end

      it("redirects") { expect(create).to redirect_to product_path(Product.last) }
      it("flashes") { expect(create).to set_flash.to('Product got created!') }
    end
  end
end

这篇关于rspec + shoulda:设置数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆