rspec + shoulda:设置数据 [英] rspec + shoulda: setting up data
问题描述
我有以下测试.共有三个 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屋!