为什么“uniqueness:true”验证在我的测试(Rails)中不起作用?

问题描述 投票:2回答:2

在我的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

在此先感谢您的帮助。

ruby-on-rails ruby validation unique minitest
2个回答
3
投票

根据the documentation on create

请注意,该记录没有id。它一直没有坚持下去。使用.errors.full_messages检查错误,以查看唯一性验证失败。

无论对象是否已成功保存到数据库,都会返回结果对象。

你应断言它已保存,如:

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

哪里告诉你它是否已被保存。或者你可以使用create!,如果它失败将提升ActiveRecord::RecordInvalid


1
投票

为了将来参考和观看这个问题的任何人 - 我用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
© www.soinside.com 2019 - 2024. All rights reserved.