RSpec / FactoryGirl中的“名称已被采用”,具有多个关联

时间:2016-02-08 11:09:42

标签: ruby-on-rails rspec rspec-rails

我正在尝试运行一个非常基本的规范测试,它失败并显示错误“名称已被采取”。

更新属于用户,其中包含许多角色

用户模型

# == Schema Information
#
# Table name: users
#
#  id                     :integer          not null, primary key
#  email                  :string           default(""), not null
#

FactoryGirl.define do
  factory :user_engineer, class: User do
    id 1
    email 'someone@somewhere.com'
    roles {[FactoryGirl.create(:engineer)]}
  end
end

角色模型

# == Schema Information
#
# Table name: roles
#
#  id          :integer          not null, primary key
#  name        :string
#  description :text
#

FactoryGirl.define do
  factory :engineer, class: Role do
    id 3
    name 'Engineer'
    description 'He is the chosen one'
  end
end

更新型号

# == Schema Information
#
# Table name: updates
#
#  id            :integer          not null, primary key
#  content       :text
#  user_id       :integer
#  ticket_id :integer
#

FactoryGirl.define do
  factory :update do
    content "This is a test update"
    association :user, factory: :user_engineer
  end
end

update_spec.rb

require 'rails_helper'

RSpec.describe Update, type: :model do
  let(:update){ FactoryGirl.create :update }
  it { expect(update).to be_valid }
end

这是错误:

Update
  example at ./spec/models/update_spec.rb:19 (FAILED - 1)

Failures:

  1) Update 
     Failure/Error: roles {[FactoryGirl.create(:engineer)]}

     ActiveRecord::RecordInvalid:
       Validation failed: Name has already been taken

我如何通过测试?!

编辑:通过添加我建议的序列行,运行RAILS_ENV=test rake db:drop后出现以下错误:

1) Update 
     Failure/Error: roles {[FactoryGirl.create(:engineer)]}

     ActiveRecord::RecordNotUnique:
       PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "roles_pkey"
       DETAIL:  Key (id)=(3) already exists.
       : INSERT INTO "roles" ("id", "name", "description", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"

2 个答案:

答案 0 :(得分:2)

从您的错误中可以看出,name属性上有 uniq 验证,您应该使用sequence技术。

FactoryGirl.define do
  factory :engineer, class: Role do
    id 3
    sequence(:name) { |n| "Engineer-#{n}" }
    description 'He is the chosen one'
  end
end

答案 1 :(得分:0)

请尝试以下用户模型代码

FactoryGirl.define do
  factory :user_engineer, class: User do
    id 1
    email 'someone@somewhere.com'
    roles {[FactoryGirl.create(:engineer, name: "new_engineer")]}
  end
end

由于name属性存在uniq约束,我认为测试数据库中已经存在工程记录,这是第一次运行测试用例时添加的,因此在运行测试之前或之后更好地清除测试数据库例。

将以下代码块放在spec / rails_helper.rb文件中。

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end