Почему проверка «уникальность: истина» не работает в моем тесте (Rails)? - PullRequest
2 голосов
/ 05 апреля 2019

В моем приложении Rails я пытаюсь сохранить MAC-адреса для устройств, принадлежащих разным пользователям.Каждый MAC-адрес должен быть уникальным, поэтому я включил проверку уникальности.Кажется, что сама проверка работает, поскольку дубликаты записей были отклонены, когда я попытался использовать консоль Rails (ActiveRecord::RecordNotUnique).Тем не менее, мой тест, чтобы проверить, что могут быть сохранены только уникальные записи, не проходит.

Поэтому мои вопросы:

  1. Почему мой тест не пройден и как я могу это исправить?
  2. Я читал в другом месте, что только проверка уникальности не является надежным способом обеспечения уникальности.Должен ли я использовать другие методы, такие как before_save обратные вызовы?

Это сообщение об ошибке, которое я получаю для теста:

Expected #<MacAddress id: nil, user_id: nil, address: "MACADD123", created_at: nil, updated_at: nil> to be nil or false

Настройка в файлах моей модели:

# app/models/mac_address.rb

class MacAddress < ApplicationRecord
  validates :address, uniqueness: true
  belongs_to :user
end
# app/models/user.rb

class User < ApplicationRecord
  has_many :mac_addresses, dependent: :destroy
end

Тест для проверки уникальности:

class MacAddressTest < ActiveSupport::TestCase
test 'mac address must be unique' do
    new_mac = 'MACADD123'
    assert MacAddress.create(user: User.first, address: new_mac)
    assert MacAddress.all.pluck(:address).include?(new_mac)

    # The 'assert_not' below is failing.
    assert_not MacAddress.create(user: User.second, address: new_mac)
  end
end

Спасибо за любую помощь заранее.

Ответы [ 2 ]

3 голосов
/ 05 апреля 2019

Согласно документации по create:

Обратите внимание, что для этой записи нет id. Это не было сохранено. Проверьте наличие ошибок с помощью .errors.full_messages, чтобы увидеть ошибку проверки уникальности.

Полученный объект возвращается независимо от того, был ли объект успешно сохранен в базе данных или нет.

Вы должны утверждать, что оно сохранено, как:

mac_address = MacAddress.create(...)
assert !mac_address.new_record?

Где это говорит вам, был ли он сохранен или нет. В качестве альтернативы вы можете использовать create!, который повысит ActiveRecord::RecordInvalid в случае неудачи.

1 голос
/ 05 апреля 2019

Для дальнейшего использования и для просмотра этого вопроса - я переписал свой тест с save вместо create, как показано ниже:

test 'mac address must be unique' do
    test_address = 'MACADD123'
    original_mac = MacAddress.new(user: User.first, address: test_address)
    duplicate_mac = MacAddress.new(user: User.second, address: test_address)

    assert original_mac.save
    assert MacAddress.pluck(:address).include?(test_address)
    assert_not duplicate_mac.save
    duplicate_mac.errors.messages[:address].include?('has already been taken')
end
...