ruby-on-rails - 具有自定义验证的 Shoulda Matcher 导致所有 shoulda 验证失败

标签 ruby-on-rails validation rspec

我遇到了一个问题,我的模型上的自定义验证导致所有 shoulda 验证失败。

本质上:

class User < ActiveRecord::Base
  validates_presence_of :name
  validate :some_date_validation

  private

  def some_date_validation
    if date_given > birthday
      errors.add(:birthday, "Some sort of error message")
    end
  end
end

然后在规范中:

require 'rails_helper'

RSpec.describe User, type: :model do
  describe "shoulda validations" do
    it { should validate_presence_of(:name) }
  end
end

这将导致我的测试失败,因为其他验证不会通过。这是为什么?

最佳答案

您需要使用默认有效的对象实例进行测试。

当您在 Rspec 测试中使用隐式主题时,Rspec 将使用默认初始化程序为您创建被测对象的新实例。在本例中,User.new。此实例将无效,因为 name 不存在,自定义验证也不会通过。

如果您正在使用工厂(例如 factory_girl),那么您应该创建一个 User 工厂来设置所有使验证通过的属性。

FactoryGirl.define do
  factory :user do
    name "John Doe"
    date_given Time.now
    birthday 25.years.ago
  end
end

然后在你的测试中使用它

require 'rails_helper'

RSpec.describe User, type: :model do
  describe "shoulda validations" do
    subject { build(:user) }
    it { should validate_presence_of(:name) }
  end
end

您现在已经明确地将测试主题设置为您的工厂创建的 User 的新实例。这些属性将被预先设置,这意味着您的实例在默认情况下是有效的,并且测试现在应该能够正确地测试每个单独的验证。

关于ruby-on-rails - 具有自定义验证的 Shoulda Matcher 导致所有 shoulda 验证失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32641595/

相关文章:

jquery - 使用 validate 时更改 select 的类

testing - 调用我在 before block 中测试的方法是不好的做法吗?

ruby-on-rails - 修改设计重置密码错误文本

ruby-on-rails - 如何模拟服务对象?我应该 mock 它吗?

java - Java 中的完整日期验证

ruby-on-rails - Rails 在哪里存储通过在测试期间保存 activerecord 对象创建的数据?

ruby-on-rails - Rails::Generator 没有在 spec 文件夹中创建工厂

javascript - 将 Rails 后端添加到 JS/HTML/CSS 应用程序时,正确的文件位置是什么?

ruby-on-rails - Ruby 将 do-block 分配给数组

java - MethodArgumentNotValidException 的 validator 仅处理相同类型的约束