我的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
型号:
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
迁移:
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
错误:
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 (?, ?, ?, ?, ?)
可能是错误的原因是什么?
修改 Github回购:https://github.com/preciz/avatar_parts
答案 0 :(得分:43)
此匹配器的工作方式与其他匹配器略有不同。如前所述,如果模型的实例尚不存在,它将创建模型的实例。有时,此步骤会失败,尤其是如果您对除了唯一属性之外的任何属性具有数据库级限制。在这种情况下,解决方案是在调用
validate_uniqueness_of
之前填充这些属性。
因此,在您的情况下,解决方案将类似于:
describe "uniqueness" do
subject { AvatarPart.new(name: "something", type: "something else") }
it { should validate_uniqueness_of(:name).case_insensitive }
end
答案 1 :(得分:1)
除了上述之外,我使用的模式解决了它:
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