【问题标题】:rspec test model for minimum and maximum valuesrspec 测试模型的最小值和最大值
【发布时间】:2012-09-21 19:44:36
【问题描述】:

我在寻找测试模型中属性范围的最优雅方法时遇到了一些麻烦。我的模型看起来像:

class Entry < ActiveRecord::Base
  attr_accessible :hours

  validates :hours, presence: true, 
    :numericality => { :greater_than => 0, :less_than => 24 }
end

我的 rspec 测试如下所示:

require 'spec_helper'
describe Entry do
  let(:entry) { FactoryGirl.create(:entry) }

  subject { entry }

  it { should respond_to(:hours) }
  it { should validate_presence_of(:hours) }
  it { should validate_numericality_of(:hours) }


  it { should_not allow_value(-0.01).for(:hours) }
  it { should_not allow_value(0).for(:hours) }
  it { should_not allow_value(24).for(:hours) }
    # is there a better way to test this range?


end

此测试有效,但是否有更好的方法来测试最小值和最大值?我的方式似乎很笨拙。测试一个值的长度似乎很容易,但我没有看到如何测试一个数字的值。我尝试过这样的事情:

it { should ensure_inclusion_of(:hours).in_range(0..24) }

但这预计会出现包含错误,我无法通过测试。也许我没有正确配置它?


我最终在我的两个边界之上和之下进行了测试,如下所示。因为我不限制我测试到小数点后两位的整数。我认为对于我的应用而言,这可能已经“足够好”了。

it { should_not allow_value(-0.01).for(:hours) }
it { should_not allow_value(0).for(:hours) }
it { should allow_value(0.01).for(:hours) }
it { should allow_value(23.99).for(:hours) }
it { should_not allow_value(24).for(:hours) }
it { should_not allow_value(24.01).for(:hours) }

【问题讨论】:

  • 你的范围不是在你的测试中吗?不应该是:它{应该确保_inclusion_of(:hours).in_range(1..23) }

标签: ruby-on-rails rspec


【解决方案1】:

您正在寻找的应该匹配器是 is_greater_than 和 is_less_than 匹配器。它们可以链接到 validate_numericality_of 匹配器上,如下所示

it {should validate_numericality_of(:hours).is_greater_than(0).is_less_than(24)}

这将验证您范围内的数字是否生成有效变量,并且该范围外的数字返回的错误是正确的。你是正确的, Ensure_inclusion_of 匹配器不起作用,因为它期待不同类型的错误,但这个验证应该可以正常工作。

【讨论】:

    【解决方案2】:

    要测试是否涵盖了所有有效值,您可以编写如下内容:

    it "should allow valid values" do
      (1..24).to_a.each do |v|
        should allow_value(v).for(:hours)
    end
    

    您还可以实施边界测试。对于每个边界,可以在任何边界上、上和下进行测试,以确保条件逻辑按预期工作as posted by David Chelimsky-2。

    因此,对于 2 个边界,您总共需要进行 6 次测试。

    【讨论】:

    • 这对于大范围来说似乎不切实际。如果您想测试一系列浮点数怎么办?
    • 这对浮点数不起作用:“迭代元素 rng,依次将每个元素传递给块。只有当范围的起始对象支持 succ 方法时,您才能进行迭代(这意味着你不能遍历 Float 对象的范围)。” ruby-doc.org/core-1.9.3/Range.html
    • 好的,感谢您提供指向 David Chelimsky 帖子的链接。测试边界是有意义的,即使它有点“笨拙”。我希望有这样的东西,除了值而不是长度:它 { should ensure_length_of(:password).is_at_least(6).is_at_most(20) } 看起来最小/最大验证匹配器很容易设置,但我现在会以“手动”方式进行。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2019-01-02
    • 1970-01-01
    • 2016-04-10
    相关资源
    最近更新 更多