使用shoulda匹配器无法获得唯一性验证测试通过

Bar*_*acs 16 ruby sqlite ruby-on-rails shoulda ruby-on-rails-3

我的avatar_parts_spec.rb中有一个shoulda匹配器,我无法通过它:

测试:

require 'rails_helper'

RSpec.describe AvatarPart, :type => :model do
  it { should validate_presence_of(:name) }
  it { should validate_presence_of(:type) }
  it { should validate_uniqueness_of(:name).case_insensitive }
  it { should belong_to(:avatar) }
end
Run Code Online (Sandbox Code Playgroud)

模型:

class AvatarPart < ActiveRecord::Base
  attr_accessible :name, :type, :avatar_id

  belongs_to :avatar

  validates_uniqueness_of :name, case_sensitive: false
  validates :name, :type, presence: true, allow_blank: false
end
Run Code Online (Sandbox Code Playgroud)

移民:

class CreateAvatarParts < ActiveRecord::Migration
  def change
    create_table :avatar_parts do |t|
      t.string :name, null: false
      t.string :type, null: false
      t.integer :avatar_id      

      t.timestamps
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

错误:

 1) AvatarPart should require unique value for name
     Failure/Error: it { should validate_uniqueness_of(:name).case_insensitive }
     ActiveRecord::StatementInvalid:
       SQLite3::ConstraintException: NOT NULL constraint failed: avatar_parts.type: INSERT INTO "avatar_parts" ("avatar_id", "created_at", "name", "type", "updated_at") VALUES (?, ?, ?, ?, ?)
Run Code Online (Sandbox Code Playgroud)

可能是错误的原因是什么?

编辑: Github回购:https://github.com/preciz/avatar_parts

Dav*_*kin 44

匹配器的文档说:

这个匹配器的工作方式与其他匹配器略有不同.如前所述,如果模型的实例尚不存在,它将创建模型的实例.有时,此步骤会失败,尤其是如果您对除了唯一属性之外的任何属性都有数据库级限制.在这种情况下,解决方案是在调用之前填充这些属性validate_uniqueness_of.

所以在你的情况下,解决方案将是这样的:

  describe "uniqueness" do
    subject { AvatarPart.new(name: "something", type: "something else") }
    it { should validate_uniqueness_of(:name).case_insensitive }
  end
Run Code Online (Sandbox Code Playgroud)

  • @VishalVijay那是在最初的问题中,它不是答案中特别重要的部分. (3认同)

dro*_*att 5

除了上述之外,我使用的一种模式可以解决它:

RSpec.describe AvatarPart, :type => :model
  describe 'validations' do
    let!(:avatar_part) { create(:avatar_part) }

    it { should validate_uniqueness_of(:some_attribute) }
    it { should validate_uniqueness_of(:other_attribute) }
  end
end
Run Code Online (Sandbox Code Playgroud)