Rails自定义模型验证器失败了rspec测试

时间:2018-02-22 00:21:55

标签: ruby-on-rails activerecord rspec

我有一个自定义验证器来验证数据库中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)>'

此时此刻,我对现在的错误感到茫然。任何帮助深表感谢! THX!

1 个答案:

答案 0 :(得分:0)

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

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