简体   繁体   English

Rspec失败,因为名称已被使用

[英]Rspec fails for Name has already been taken

I'm trying to make rspec testcases. 我正在尝试制作rspec测试用例。 But, Rspec fails for Name has already been taken. 但是,Rspec失败,因为已经使用了Name。

It seems "let" evalulated each time "product" called. 每次调用“产品”时,似乎都会评估“让”。

How can I fix it? 我该如何解决?

Console 安慰

./spec/models/spree/product_decorator_spec.rb:31:in `block (4 levels) in <top (required)>'

ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
./spec/models/spree/product_decorator_spec.rb:6:in `block (3 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:20:in `block (4 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:23:in `block (4 levels) in <top (required)>'

ActiveRecord::RecordInvalid: Validation failed: Name has already been taken
./spec/models/spree/product_decorator_spec.rb:6:in `block (3 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:12:in `block (4 levels) in <top (required)>'
./spec/models/spree/product_decorator_spec.rb:15:in `block (4 levels) in <top (required)>'

product_decorator_spec.rb product_decorator_spec.rb

require 'spec_helper'

describe Spree::Product do

  context '#create' do
    let(:us) { create(:zone, name: "US") }
    let(:china) { create(:zone, name: "China") }
    let(:japan) { create(:zone, name: "Japan") }


    context "when a product has no ng zone" do
      let(:product) { create(:product, zones: [us, china, japan]) }

      it "should get ng_zones correctly" do
        product.ng_zones.should match_array []
      end
    end

    context "when a product has one ng zone" do
      let(:product) { create(:product, zones: [us, china]) }

      it "should get ng_zones correctly" do
        product.ng_zones.should match_array ["Japan"]
      end
    end

    context "when a product has two ng zone" do
      let(:product) { create(:product, zones: [us]) }

      it "should get ng_zones correctly" do
        product.ng_zones.should match_array ["China", "Japan"]
      end
    end
  end
end

The body of the let is evaluated with every it block. let的主体将与每个it块一起评估。 I'm assuming you have a uniqueness constraint on your Zone classes. 我假设您在Zone类上具有唯一性约束。

You have 2 possibilities 你有两种可能性

  • Either build the variables in a before(:all) block and assign them to something like @us 要么在before(:all)块中构建变量, before(:all)将其分配给类似@us
  • Clean up your database after(:each) after(:each)清理数据库

You are testing the Product#create so, you won't need to really create zones for this particular test. 您正在测试Product#create因此,您无需为该特定测试真正创建zones

Instead you could just use build_stubbed method. 相反,您可以只使用build_stubbed方法。

let(:us) { build_stubbed(:zone, name: "US") }
let(:china) { build_stubbed(:zone, name: "China") }
let(:japan) { build_stubbed(:zone, name: "Japan") }

This way, it's creation process are not going to rely on the database and also the validations for the Zone model and you have an awesome performance boost since you are not hitting the db for for each single test. 这样,它的创建过程将不再依赖数据库以及Zone模型的验证,并且由于没有为每个测试命中db,因此性能得到了极大的提高。

You can read about build_stubbed here . 您可以在此处阅读有关build_stubbed 信息

Please let me know if it helps you somehow. 请让我知道它是否对您有帮助。 ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM