简体   繁体   English

Rails定制模型验证器未通过RSpec测试

[英]Rails custom model validator fails rspec tests

I have a custom validator to verify the content of 2 fields in my database. 我有一个自定义验证器来验证数据库中2个字段的内容。 When I use it through my UI, it works fine, however my rspec tests are failing and I can't understand why. 当我通过UI使用它时,它可以正常工作,但是我的rspec测试失败了,我不明白为什么。

Here is the rspec test: 这是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

The Device model is: 设备型号为:

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

And my ip_validator concern is: 而我的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

Ironically, the validator is correctly passing the should_not allow_value tests, however the should allow_value tests are failing: 具有讽刺意味的是,验证器正确地通过了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)>'

At this point, I'm at a loss as to what is wrong now. 在这一点上,我不知所措。 Any help is much appreciated! 任何帮助深表感谢! Thx! 谢谢!

I found the solution. 我找到了解决方案。 I don't know why, but the RSPEC doesn't know the $LAST_MATCH_INFO . 我不知道为什么,但是RSPEC不知道$LAST_MATCH_INFO If you replace it with $~ , what it is actually is, it should work. 如果将它替换为$~ ,它实际上是,它应该可以工作。 At least, it works for me. 至少,它对我有用。

$LAST_MATCH_INFO is part of the library English which should be enabled in Rspec probably. $LAST_MATCH_INFOEnglish库的一部分,可能应该在$LAST_MATCH_INFO中启用。 But for me, the problem is resolved. 但是对我来说,问题已经解决了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM