web-dev-qa-db-ja.com

shouldaマッチャーで一意性検証テストに合格できません

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

18
Barna Kovacs

ドキュメント そのマッチャーの場合:

このマッチャーは、他のマッチャーとは少し動作が異なります。前述のように、モデルのインスタンスがまだ存在しない場合は、インスタンスが作成されます。特に、一意の属性以外の属性にデータベースレベルの制限がある場合は、この手順が失敗することがあります。この場合の解決策は、validate_uniqueness_ofを呼び出す前にこれらの属性にデータを入力することです。

したがって、あなたの場合、解決策は次のようになります。

  describe "uniqueness" do
    subject { AvatarPart.new(name: "something", type: "something else") }
    it { should validate_uniqueness_of(:name).case_insensitive }
  end
46
Dave Slutzkin

上記に加えて、それを解決するために私が使用したパターン:

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
1
drosenblatt