【问题标题】:Why are tests failing due to validation?为什么测试由于验证而失败?
【发布时间】:2021-02-25 09:32:06
【问题描述】:

我正在为应用程序编写测试并遇到了问题。

我的模型有下一个验证:

  def correct_date
    errors.add(:occured_at, 'must be in past or present time') if occured_at > 5.minutes.from_now
  end

当我在模型上运行最简单的测试时,它们都会失败。

  describe 'associations' do
    it { should belong_to(:category).optional }
  end

我收到一个错误:

     Failure/Error: errors.add(:occured_at, 'must be in past or present time') if occured_at > 5.minutes.from_now
     
     NoMethodError:
       undefined method `>' for nil:NilClass

【问题讨论】:

    标签: ruby-on-rails ruby rspec rspec-rails shoulda-matchers


    【解决方案1】:

    默认情况下,该测试将通过简单的Model.new 调用创建一个新对象(其中Model 是正在测试的模型类)。在您的情况下,Model.new 不会产生有效对象,因此您需要告诉 Rspec 用于这些测试的主题:

    describe 'associations' do
      subject { FactoryBot.create(:whatever_the_factory_is_called) }
    
      it { should belong_to(:category).optional }
    end
    

    您还应该修复您的correct_date 验证方法以处理occurred_at.nil?;要么在correct_date 中验证它不是nil:

    def correct_date
      if(occurred_at.nil?)
        # complain
      elsif(occurred_at > 5.minutes.from_now)
        errors.add(:occured_at, 'must be in past or present time')
      end
    end
    

    或单独验证存在并在occurred_at.nil?时跳过>:

    validates :occurred_at, presence: true
    
    def correct_date
      errors.add(:occured_at, 'must be in past or present time') if occurred_at && occured_at > 5.minutes.from_now
    end
    

    在数据库not null 中创建occurred_at 列也是可取的。

    如果occurred_at 确实是可选的,那么您只需更新correct_date 以考虑occurred_at.nil?:

    def correct_date
      errors.add(:occured_at, 'must be in past or present time') if occurred_at && occured_at > 5.minutes.from_now
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2018-04-04
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      相关资源
      最近更新 更多