Ruby on rails Rails:小于验证使RSpec测试失败

Ruby on rails Rails:小于验证使RSpec测试失败,ruby-on-rails,ruby,unit-testing,validation,rspec,Ruby On Rails,Ruby,Unit Testing,Validation,Rspec,使用: Ruby 2.6.6 轨道6.0.2.2 我有一个型号,Part,它有两个字段,quantity\u available和minimum\u order 我进行了以下验证以确保: 最小订单和可用数量必须存在 最小订单和可用数量不能为0或负值 最小订单的值不能大于可用数量 类部分{可用数量} 我想我可能已经找到了一个好的解决方案,它不仅仅是一个解决方案,实际上并不能解决我在测试中遇到的原始问题 在rails c中运行以下命令会引发验证错误,如预期的那样: new=Part.crea

使用:

  • Ruby 2.6.6
  • 轨道6.0.2.2
我有一个型号,
Part
,它有两个字段,
quantity\u available
minimum\u order

我进行了以下验证以确保:

  • 最小订单
    和可用数量必须存在
  • 最小订单
    可用数量
    不能为0或负值
  • 最小订单
    的值不能大于可用数量
类部分
当我使用
rails控制台
手动测试它以创建与上述验证冲突的新部件时,验证工作正常,但是我的一个RSpec测试失败

#RSpec
RSpec.description Part,type::model do
let(:part){part.new(可用数量:250,最小订单:10)}
它“没有可用数量无效”do
零件数量\可用数量=零
期望(部分)无效
结束
结束
#控制台错误
失败:
1) 没有可用数量的零件基本检查无效
失败/错误:预期(部分)。无效
类型错误:
无法将零转换为浮点
#./spec/models/part_spec.rb:32:in'block(3层)in'
正如您所看到的,这是一个非常简单的测试,它简单地说明没有可用的
quantity\u
的零件应该失败,但是在这种情况下,它在技术上确实失败了,只是不是以我希望它失败的方式

我最好的猜测是,它可能与在测试中将
quantity\u available
声明为
nil
有关,因为它无法验证所有3个条件,因此会在某个地方导致导线交叉。我有一个与上面的测试相同的
最小顺序测试,但是这个测试按预期通过了


我在这里做错了什么?

我想符号没有真正计算为字段值,请重试 像这样传递一个lambda:

验证:最小顺序的数值性,
仅_整数:true,
小于:->{可用数量}

我想我可能已经找到了一个好的解决方案,它不仅仅是一个解决方案,实际上并不能解决我在测试中遇到的原始问题

rails c
中运行以下命令会引发验证错误,如预期的那样:

new=Part.create(可用数量:0,最小订单:10)
new.save#=>false
new.errors.full_messages#=>[“可用数量必须大于0”,“最小订单必须小于或等于0”]
正如您所看到的,这两个验证完全按照预期工作,但测试中的问题是,一个验证实际上妨碍了另一个验证,这显然会导致测试通过时出现问题

在这一点上,我看到了两个选项,以便继续:

  • 使这一特定测试的
    最小顺序字段也有一个零值。
  • 这会导致一些小的代码重复,只是总体上不适合我的口味

  • 如果
    可用数量\u
    字段的当前值为零或0,只需跳过验证即可。
  • 这个更有意义。毕竟,第一次验证将确保0不会进入这些字段中的任何一个的DB,因此,如果存在0或nil,则跳过第二次验证是安全的。如果不是,验证将启动,然后才比较这两个值

    因此,解决方案非常简单;只需在评估lambda的验证中插入一个
    ,除非:

    验证:最小订单的数量,小于::可用数量,除非:->{quantity\u available.nil?| quantity\u available==0}
    

    这样,所有的测试都是绿色的,不需要任何变通方法,而且我很确定我的模型在验证检查中是最有效的一点

    可能是因为
    只有_integer
    期望它是一个整数,而
    nil
    不是一个整数。这是在引擎盖下做的。您可以执行一个
    expect raise\u error
    。我没有考虑
    仅\u integer
    位,但这是有意义的。删除了它,但同样的情况仍在发生,所以现在我只是将测试转换为
    expect{part.save}。以引发_error TypeError
    ,现在就可以了。干杯您确信这是预期行为吗?我认为这是一个解决办法。@AmitPatel你说得对,它确实感觉像是一个忽略了这个问题的解决办法。见下面我的答案