【问题标题】:Rails custom model validator fails rspec testsRails 自定义模型验证器未通过 rspec 测试
【发布时间】:2018-02-22 00:21:55
【问题描述】:

我有一个自定义验证器来验证我的数据库中 2 个字段的内容。当我通过 UI 使用它时,它工作正常,但是我的 rspec 测试失败了,我不明白为什么。

这是 rspec 测试:

require 'rails_helper'
RSpec.describe Device, type: :model do
  before(:each) { @user = User.create(email: 'test@test.com', password: 'password', password_confirmation: 'password') }
  before(:each) { @device = Device.create(user_id: @user.id) }
  subject { @device }
  it { should allow_value('192.168.1.1').for(:ips_scan) }
  it { should allow_value('192.168.1.1').for(:ips_exclude) }

  it { should_not allow_value('192.168.1.1, a.b.c.d').for(:ips_scan) }
  it { should_not allow_value('a.b.c.d').for(:ips_exclude) }
end

设备型号为:

class Device < ApplicationRecord
  belongs_to :user
  validates :ips_scan, :ips_exclude, ip: true, on: :update
end

我关心的 ip_validator 是:

class IpValidator < ActiveModel::Validator
  def validate(record)
    if record.ips_scan
      ips = record.ips_scan.split(',')
      ips.each do |ip|
        /([0-9]{1,3}\.){3}[0-9]{1,3}(\/([1-2][0-9]|[0-9]|3[0-2]))?(-([0-9]{1,3}))?/ =~ ip
        record.errors.add(:ips_scan, 'is not valid') unless $LAST_MATCH_INFO
      end
    end

    if record.ips_exclude
      ips = record.ips_exclude.split(',')
      ips.each do |ip|
        /([0-9]{1,3}\.){3}[0-9]{1,3}(\/([1-2][0-9]|[0-9]|3[0-2]))?(-([0-9]{1,3}))?/ =~ ip
        record.errors.add(:ips_exclude, 'is not valid') unless $LAST_MATCH_INFO
      end
    end
  end
end

具有讽刺意味的是,验证器正确地通过了 should_not allow_value 测试,但是 should allow_value 测试失败了:

Failures:

  1) Device should allow :ips_scan to be ‹"192.168.1.1"›
     Failure/Error: it { should allow_value('192.168.1.1').for(:ips_scan) }

       After setting :ips_scan to ‹"192.168.1.1"›, the matcher expected the
       Device to be valid, but it was invalid instead, producing these
       validation errors:

       * ips_scan: ["is not valid"]
     # ./spec/models/device_spec.rb:22:in `block (2 levels) in <top (required)>'

  2) Device should allow :ips_exclude to be ‹"192.168.1.1"›
     Failure/Error: it { should allow_value('192.168.1.1').for(:ips_exclude) }

       After setting :ips_exclude to ‹"192.168.1.1"›, the matcher expected the
       Device to be valid, but it was invalid instead, producing these
       validation errors:

       * ips_exclude: ["is not valid"]
     # ./spec/models/device_spec.rb:23:in `block (2 levels) in <top (required)>'

在这一点上,我不知道现在出了什么问题。任何帮助深表感谢!谢谢!

【问题讨论】:

  • 嗨,我也有一些无法解释的问题,我的方法也是使用 $LAST_MATCH_INFO。我认为它可能是,Rspec 无法处理它。我找不到任何关于 rspec 和 $LAST_MATCH_INFO 的信息。

标签: ruby-on-rails activerecord rspec


【解决方案1】:

我找到了解决方案。我不知道为什么,但 RSPEC 不知道 $LAST_MATCH_INFO。如果你用$~ 替换它,它实际上是什么,它应该可以工作。至少,它对我有用。

$LAST_MATCH_INFO 是库 English 的一部分,可能应该在 Rspec 中启用。但对我来说,问题已经解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2019-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多