简体   繁体   English

为什么“唯一性:真实”验证在我的测试中不起作用(Rails)?

[英]Why is the “uniqueness: true” validation not working in my test (Rails)?

In my Rails app, I am trying to save MAC addresses for devices belonging to different users. 在我的Rails应用程序中,我试图为属于不同用户的设备保存MAC地址。 Each MAC address must be unique, so I included the uniqueness validation. 每个MAC地址必须是唯一的,因此我包括了唯一性验证。 The validation itself seems to be working, since duplicate records were rejected when I tried using the Rails Console ( ActiveRecord::RecordNotUnique ). 验证本身似乎正在起作用,因为当我尝试使用Rails控制台( ActiveRecord::RecordNotUnique )时,重复记录被拒绝了。 However, my test to check that only unique records can be saved is failing. 但是,我检查只能保存唯一记录的测试失败了。

So my questions are: 所以我的问题是:

  1. Why is my test failing and how can I fix it? 为什么我的测试失败了,我该如何解决?
  2. I read elsewhere that the uniqueness validation alone is not a reliable way to assure uniqueness. 我在其他地方读到过,仅凭唯一性验证并不是确保唯一性的可靠方法。 Should I use other methods, such as before_save callbacks? 我是否应该使用其他方法,例如before_save回调?

This is the error message I'm getting for the test: 这是我要进行测试的错误消息:

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

Setup in my model files: 在我的模型文件中进行设置:

# 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

Test to check for uniqueness: 测试以检查唯一性:

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

Thanks for any help in advance. 感谢您的任何帮助。

As per the documentation on create : 根据有关create的文档

Notice there's no id for that record. 请注意,该记录没有id It hasn't been persisted. 它尚未持久。 Check for errors with .errors.full_messages to see the uniqueness validation failure. 使用.errors.full_messages检查错误以查看唯一性验证失败。

The resulting object is returned whether the object was saved successfully to the database or not. 无论对象是否成功保存到数据库,都将返回结果对象。

You should assert that it's saved, like: 您应该断言它已保存,例如:

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

Where that tells you if it's been saved or not. 告诉您是否已保存的位置。 Alternatively you can use create! 或者,您可以使用create! which will raise ActiveRecord::RecordInvalid if it failed. 如果失败,它将引发ActiveRecord::RecordInvalid

For future reference and for anyone viewing this question - I rewrote my test with save instead of create like below: 供以后参考和任何查看此问题的人员-我用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM