Rails rspec 应该使用匹配器来验证不区分大小写的项目的唯一性失败吗?

Jas*_*lis 5 rspec ruby-on-rails shoulda

我正在努力成为一名优秀的 Rails 开发人员并编写测试。我遇到了一些不清楚的事情,正在寻求建议。我有一个具有独特的不区分大小写属性的模型。然而测试失败了。测试这个的正确方法是什么?我究竟做错了什么?

class Tenant < ApplicationRecord
  validates :name, presence: true
  validates :name, uniqueness: { case_sensitive: false }
end

RSpec.describe Tenant, type: :model do
  it { should validate_presence_of :name }
  it { should validate_uniqueness_of(:name).case_insensitive }
end
Run Code Online (Sandbox Code Playgroud)

看起来它正在尝试设置 id,nil即使我们有另一个需要存在的验证。但为什么在测试名称时要这样做呢?我很困惑。

测试显示以下结果;

Failures:

 1) Tenant Validates Uniqueness of should validate that :name is case-insensitively unique
 Failure/Error: self.id = self.id.downcase

 NoMethodError:
   undefined method `downcase' for nil:NilClass
 # ./app/models/tenant.rb:17:in `block in <class:Tenant>'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:96:in `perform_validation'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:89:in `validation_result'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:85:in `validation_error_messages'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:64:in `messages'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:25:in `has_messages?'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:55:in `messages_match?'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validator.rb:21:in `call'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:38:in `matches?'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:24:in `each'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:24:in `detect'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb:24:in `first_passing'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher.rb:533:in `public_send'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher.rb:533:in `run'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/allow_value_matcher.rb:400:in `does_not_match?'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/disallow_value_matcher.rb:32:in `matches?'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validation_matcher.rb:155:in `run_allow_or_disallow_matcher'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_model/validation_matcher.rb:93:in `disallows_value_of'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:606:in `validate_two_records_with_same_non_blank_value_cannot_coexist?'
 # /Users/a/.rvm/gems/ruby-2.5.0/gems/shoulda-matchers-3.1.2/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb:330:in `matches?'
 # ./spec/models/tenant_spec.rb:49:in `block (3 levels) in <top (required)>'

 Finished in 0.09495 seconds (files took 1.89 seconds to load)
 2 examples, 1 failure

 Failed examples:

 rspec ./spec/models/tenant_spec.rb:49 # Tenant Validates Uniqueness of should validate that :name is case-insensitively unique
Run Code Online (Sandbox Code Playgroud)

注意:这可能是一些愚蠢而明显的事情,我只是错过了。感谢您的帮助/建议。

版本:Ruby 2.50 :: Rails 5.14 :: Rspec 3.7 :: Shoulda-matcher 3.12

Jas*_*lis 1

正如纳特福德提到的

看来您定义了一些之前/之后的挂钩。请显示Tenant模型类的更多代码。

这是一个预先安排的问题。