Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在RSpec中使用正则表达式测试模型验证?_Ruby On Rails_Ruby_Regex_Rspec_Rspec Rails - Fatal编程技术网

Ruby on rails 如何在RSpec中使用正则表达式测试模型验证?

Ruby on rails 如何在RSpec中使用正则表达式测试模型验证?,ruby-on-rails,ruby,regex,rspec,rspec-rails,Ruby On Rails,Ruby,Regex,Rspec,Rspec Rails,经过一点黑客攻击之后,我提出了以下测试,以确保我的模型验证器上的正则表达式模式正常工作。我想知道是否有更好的方法来测试这些条件,而不是构建一个坏字符串。我想说明批准的正则表达式模式之外的所有字符。不同的列也可能有不同的验证器 型号 validates :provider_unique_id, presence: true, length: { maximum: 50 }, format: { with: /\A[A-Za-z0-9

经过一点黑客攻击之后,我提出了以下测试,以确保我的模型验证器上的正则表达式模式正常工作。我想知道是否有更好的方法来测试这些条件,而不是构建一个坏字符串。我想说明批准的正则表达式模式之外的所有字符。不同的列也可能有不同的验证器

型号

validates :provider_unique_id,
           presence: true,
           length: { maximum: 50 },
           format: { with: /\A[A-Za-z0-9]+\z/ }
规格

describe 'provider unique id' do
  let(:bad_string) { (0..255).map(&:chr).select { |x| x != /\A[A-Za-z0-9]+\z/ }.sample(20).join }

  it 'should exist' do
    shop.provider_unique_id = nil
    expect(shop.valid?).to be_falsey
  end

  it 'passes regex rules' do
    shop.provider_unique_id = bad_string
    expect(shop.valid?).to be_falsey
  end
end

如果我非常彻底的话,我会这样写。想象一下测试驱动验证,一次添加一个测试并添加到验证中以使其通过

describe '#provider_unique_id' do
  %w(a z).each do |letter|
    it "can be letter #{letter}" do
      expect_to_be_valid letter
    end
  end

  # after making this pass, I'd change the regex to use the i flag so I wouldn't need to test for Z
  it "can be uppercase" do
    expect_to_be_valid 'A'
  end

  [0, 9].each do |digit|
    it "can be digit #{digit}" do
      expect_to_be_valid digit
    end
  end

  it "can be more than one character" do
    expect_to_be_valid '00'
  end

  it "isn't nil" do
    expect_to_be_invalid nil
  end

  it "isn't blank" do
    expect_to_be_invalid ""
  end

  it "can be 50 characters long" do
    expect_to_be_valid('0' * 50)
  end

  it "can't be longer than 50 characters" do
    expect_to_be_invalid('0' * 51)
  end

  # I chose _ as a non-alphanumeric since it's the only non-alphanumeric word character.
  # That is, it's as close to a valid character as it can be without be valid.
  it "can't contain a non-alphanumeric character" do
    expect_to_be_invalid '_'
  end

  # this example forces you to add \A
  it "can't begin with a non-alphanumeric character" do
    expect_to_be_invalid '_0'
  end

  # this example forces you to add \z
  it "can't end with a non-alphanumeric character" do
    expect_to_be_invalid '0_'
  end

  def expect_to_be_valid(provider_unique_id)
    shop.provider_unique_id = provider_unique_id
    expect(shop).to be_valid
  end

  def expect_to_be_invalid(provider_unique_id)
    shop.provider_unique_id = provider_unique_id
    expect(shop).to_not be_valid
  end

end
我不会随机生成一个坏字符串,因为它不会强迫您编写任何额外的代码。我认为用
\uu
进行测试就足够了。请注意,有比ASCII 0-255多得多的字符,并且对它们进行测试是不切实际的


您可以想象通过测试每个范围前后的字符来检查正则表达式中的范围(
a-z
a-z
0-9
),但不太可能有人编写错误包含这些字符的代码,所以我不会走那么远。

如果我非常彻底的话,我会这样写。想象一下测试驱动验证,一次添加一个测试并添加到验证中以使其通过

describe '#provider_unique_id' do
  %w(a z).each do |letter|
    it "can be letter #{letter}" do
      expect_to_be_valid letter
    end
  end

  # after making this pass, I'd change the regex to use the i flag so I wouldn't need to test for Z
  it "can be uppercase" do
    expect_to_be_valid 'A'
  end

  [0, 9].each do |digit|
    it "can be digit #{digit}" do
      expect_to_be_valid digit
    end
  end

  it "can be more than one character" do
    expect_to_be_valid '00'
  end

  it "isn't nil" do
    expect_to_be_invalid nil
  end

  it "isn't blank" do
    expect_to_be_invalid ""
  end

  it "can be 50 characters long" do
    expect_to_be_valid('0' * 50)
  end

  it "can't be longer than 50 characters" do
    expect_to_be_invalid('0' * 51)
  end

  # I chose _ as a non-alphanumeric since it's the only non-alphanumeric word character.
  # That is, it's as close to a valid character as it can be without be valid.
  it "can't contain a non-alphanumeric character" do
    expect_to_be_invalid '_'
  end

  # this example forces you to add \A
  it "can't begin with a non-alphanumeric character" do
    expect_to_be_invalid '_0'
  end

  # this example forces you to add \z
  it "can't end with a non-alphanumeric character" do
    expect_to_be_invalid '0_'
  end

  def expect_to_be_valid(provider_unique_id)
    shop.provider_unique_id = provider_unique_id
    expect(shop).to be_valid
  end

  def expect_to_be_invalid(provider_unique_id)
    shop.provider_unique_id = provider_unique_id
    expect(shop).to_not be_valid
  end

end
我不会随机生成一个坏字符串,因为它不会强迫您编写任何额外的代码。我认为用
\uu
进行测试就足够了。请注意,有比ASCII 0-255多得多的字符,并且对它们进行测试是不切实际的


您可以想象通过测试每个范围前后的字符来检查正则表达式中的范围(
a-z
a-z
0-9
),但不太可能有人编写错误包含这些字符的代码,所以我不会走那么远。

我想测试正则表达式模式不匹配的所有情况。我不确定这是否能抓住这一点,因为它只针对特定情况进行测试。您确实为我指出了随机字符选择器是真实的,因为它可以在给定的测试运行期间选择通过的结果,但在其他测试运行中不会。我想知道我是否应该把它分成多个测试,寻找像所有符号、所有数字之类的东西……再说一遍,你不可能真正测试所有的否定情况;太多了。问题是编写下一个测试是否会促使您更改代码。我只是增加了两个测试:我意识到我没有强迫正则表达式有范围。测试z和9不会阻止您编写只匹配a、z、0和9的正则表达式,但不太可能有人会这样做,因此我不会测试更有效的情况。我想测试正则表达式模式不匹配的所有情况。我不确定这是否能抓住这一点,因为它只针对特定情况进行测试。您确实为我指出了随机字符选择器是真实的,因为它可以在给定的测试运行期间选择通过的结果,但在其他测试运行中不会。我想知道我是否应该把它分成多个测试,寻找像所有符号、所有数字之类的东西……再说一遍,你不可能真正测试所有的否定情况;太多了。问题是编写下一个测试是否会促使您更改代码。我只是增加了两个测试:我意识到我没有强迫正则表达式有范围。测试z和9不会阻止您编写只匹配a、z、0和9的正则表达式,但不太可能有人会这样做,所以我不会测试更有效的情况。