Shoulda-matcher How to validate uniqueness of enum attribute?

China☆狼群 提交于 2019-12-12 02:21:55

问题


I use rspec-rails with shoulda-matcher to test my model. Here is the code:

user_ticket.rb

class UserTicket < ActiveRecord::Base
  belongs_to :user
  belongs_to :ticket

  enum relation_type: %w( creator supporter )

  validates_uniqueness_of :relation_type, scope: [:user_id, :ticket_id]
end

user_ticket_spec.rb

RSpec.describe UserTicket, type: :model do
  subject { FactoryGirl.build(:user_ticket) }

  describe 'Relations' do
    it { should belong_to(:user) }
    it { should belong_to(:ticket) }
  end

  describe 'Validations' do
    it { should define_enum_for(:relation_type).with(%w( creator supporter )) }
    # PROBLEM HERE
    it { should validate_uniqueness_of(:relation_type).case_insensitive.scoped_to([:user_id, :ticket_id]) }
  end
end

When I run the test case the result is always:

Failure/Error: it { should validate_uniqueness_of(:relation_type).case_insensitive.scoped_to([:user_id, :ticket_id]) }

     ArgumentError:
       'CREATOR' is not a valid relation_type

I just think shoulda matcher wants to validate the uniqueness with some kinds of relation_type values: uppercase, lowercase,..etc. My question is in this situation, how to make the test pass with such of defined model validations?


回答1:


It's failing because you're asking it to test validation case insensitively. Typically this would be used to test a range of values with different cases cause validation to fail. However, you're not even allowed to set the value because of the enum; it doesn't even get to the validation check.

It is testing the validation with "creator" and "CREATOR" (at least). enums are case sensitive so these would be two different values in the enum and you've only declared "creator". When it tries to assign "CREATOR" to test the validation your enum gets upset and refuses to allow it.

You may want to validate the uniqueness without case sensitivity in which case you want:

validate_uniqueness_of(:relation_type).ignoring_case_sensitivity

From the validates_uniqueness_of docs:

By default, validate_uniqueness_of will check that the validation is case sensitive: it asserts that uniquable attributes pass validation when their values are in a different case than corresponding attributes in the pre-existing record.

Use ignoring_case_sensitivity to skip this check.

Or you might want to skip the uniqueness checks in your test altogether and trust that rails only allows unique values in an enum.



来源:https://stackoverflow.com/questions/39325946/shoulda-matcher-how-to-validate-uniqueness-of-enum-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!