Не удается пройти тест проверки уникальности с помощью соответствующих сопоставителей

У меня есть сопоставитель shoulda в моем achievement_spec.rb, и я не могу его пройти:

Спецификация:

- require 'rails_helper' 
   RSpec.describe Achievement, type: :model do  
   describe 'validations' do 
     it { should validate_presence_of(:title) }
     it { should validate_uniqueness_of(:title).case_insensitive.scoped_to(:user_id).with_message("you
   can't have two achievements with same title")}    
     it { should validate_presence_of(:user) } 
     it { should belong_to(:user) } 
end 
end

Модель:

- class Achievement < ActiveRecord::Base    belongs_to :user

    validates :title, presence: true
    validates :user, presence: true     
    validates :title, uniqueness: {
        scope: :user_id,        
        message: "you can't have two achievements with the same title"  
}   

    enum privacy: [ :public_access, :private_access, :friends_access ]

     def description_html
       Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(description) 
end
end

Ошибка:

- .F..

   Failures:

     1) Achievement validations should validate that :title is
   case-sensitively unique within the scope of :user_id, producing a
   custom validation error on failure
        Failure/Error: it { should validate_uniqueness_of(:title).scoped_to(:user_id).with_message("you
   can't have two achievements with same title") }

          Achievement did not properly validate that :title is case-sensitively
          unique within the scope of :user_id, producing a custom validation error
          on failure.
            After taking the given Achievement, setting its :title to ‹"an
            arbitrary value"›, and saving it as the existing record, then making a
            new Achievement and setting its :title to ‹"an arbitrary value"› as
            well and its :user_id to a different value, ‹nil›, the matcher
            expected the new Achievement to be invalid and to produce the
            validation error "you can't have two achievements with same title" on
            :title. The record was indeed invalid, but it produced these
            validation errors instead:

            * user: ["can't be blank"]
            * title: ["you can't have two achievements with the same title"]
        # ./spec/models/achievement_spec.rb:29:in `block (3 levels) in <top (required)>'

   Finished in 0.16555 seconds (files took 3.13 seconds to load) 4
   examples, 1 failure

   Failed examples:

   rspec ./spec/models/achievement_spec.rb:29 # Achievement validations
   should validate that :title is case-sensitively unique within the
   scope of :user_id, producing a custom validation error on failure

   [Finished in 4.1s with exit code 1] [cmd: ['rspec', '-I
   /home/mayur/Downloads/MyWork/ruby/i-rock/spec/models',
   '/home/mayur/Downloads/MyWork/ruby/i-rock/spec/models/achievement_spec.rb']]
   [dir: /home/mayur/Downloads/MyWork/ruby/i-rock] [path:
   /usr/local/rvm/gems/ruby-2.2.4/bin:/usr/local/rvm/gems/ruby-2.2.4@global/bin:/usr/local/rvm/rubies/ruby-2.2.4/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/usr/local/rvm/bin:/home/mayur/.local/bin:/home/mayur/bin]

Как я могу избавиться от вышеуказанной ошибки?

Я попробовал решение ниже, но получил ту же ошибку:

Изменение в модели:

validates :title, uniqueness: {
        case_sensitive: false,
        scope: :user_id, 
        message: "you can't have two achievements with the same title"
    }

Изменение в спецификации:

it { should validate_uniqueness_of(:title).case_insensitive.scoped_to(:user_id).with_message("you can't have two achievements with same title") }

Ошибка снова:

.F..

Failures:

  1) Achievement validations should validate that :title is case-insensitively unique within the scope of :user_id, producing a custom validation error on failure
     Failure/Error: it { should validate_uniqueness_of(:title).case_insensitive.scoped_to(:user_id).with_message("you can't have two achievements with same title") }

       Achievement did not properly validate that :title is case-insensitively
       unique within the scope of :user_id, producing a custom validation error
       on failure.
         After taking the given Achievement, setting its :title to ‹"an
         arbitrary value"›, and saving it as the existing record, then making a
         new Achievement and setting its :title to ‹"an arbitrary value"› as
         well and its :user_id to a different value, ‹nil›, the matcher
         expected the new Achievement to be invalid and to produce the
         validation error "you can't have two achievements with same title" on
         :title. The record was indeed invalid, but it produced these
         validation errors instead:

         * user: ["can't be blank"]
         * title: ["you can't have two achievements with the same title"]
     # ./spec/models/achievement_spec.rb:29:in `block (3 levels) in <top (required)>'

Finished in 0.13566 seconds (files took 3.14 seconds to load)
4 examples, 1 failure

Failed examples:

rspec ./spec/models/achievement_spec.rb:29 # Achievement validations should validate that :title is case-insensitively unique within the scope of :user_id, producing a custom validation error on failure

person Mayuresh Srivastava    schedule 23.07.2016    source источник


Ответы (2)


Сбой происходит из-за того, что сообщение об ошибке, определенное в вашей спецификации, не соответствует тому, что есть в вашей модели. В вашей спецификации отсутствует слово the:

Спецификация

...  .with_message("you can't have two achievements with same title")}

Модель

...  message: "you can't have two achievements with the same title"

Исправление того, что определено в вашей спецификации в .with_message, чтобы соответствовать тому, что определено в вашей модели в сообщении проверки уникальности в title, должно устранить ошибку.

person Mikael Kessler    schedule 29.05.2019

Вам нужно построить фабрику и убедиться, что есть пользователь, прежде чем запускать эти проверки:

describe Achievment do
  context 'validations' do
    before { FactoryGirl.build(:achievement) }

    it do
      should validate_uniqueness_of(:title).
        scoped_to(:user_id).
        case_insensitive
    end
  end
end

ваша фабрика тогда:

FactoryGirl.define do
  factory :achievement
    title 'some-string'
    user
  end
end
person Anthony    schedule 23.07.2016
comment
это прямо с главной страницы shoulda-matchers -› matchers.shoulda.io - person Anthony; 25.07.2016