【发布时间】:2009-06-01 20:59:54
【问题描述】:
我正在我的模型事物上编写规范,该模型事物的日期字段应该在创建日期之后,因此我使用 validate_timeliness 这样的插件
validate_date :date, :after Time.now
我希望能够添加一些日期较早的事物,但验证失败。我想在使用 machinist 工厂创建一些事物时绕过验证。
有什么线索吗?
【问题讨论】:
标签: ruby-on-rails ruby rspec
我正在我的模型事物上编写规范,该模型事物的日期字段应该在创建日期之后,因此我使用 validate_timeliness 这样的插件
validate_date :date, :after Time.now
我希望能够添加一些日期较早的事物,但验证失败。我想在使用 machinist 工厂创建一些事物时绕过验证。
有什么线索吗?
【问题讨论】:
标签: ruby-on-rails ruby rspec
您的验证不应该确保日期在 created_at 属性之后吗?而不是 Time.now???
您不应该尝试在测试中使用无效数据,您可能应该做的是捏造当时创建的数据。
@thing = Thing.make(:created_at => 1.day.ago)
在规范中尝试过去的唯一原因当然应该是测试验证是否确实有效..
@thing = Thing.make_unsaved(:date => 1.day.ago)
@thing.should have(1).error_on(:date)
您有这样做的理由吗?你想测试什么?
【讨论】:
如果您使用布尔参数 =true 调用 your_obj.save,如下所示:some_obj.save!(true),则将跳过所有验证。这可能是我公司广泛使用的未记录的 ActiveRecord 功能:)
【讨论】:
嗯,没有直接的方法来处理机械师本身。但是您可以尝试欺骗它...在 spec/spec_helper 中,在加载 Machinist 蓝图之前重新定义 Thing 模型。
class Thing
def before_validation
self.date = 1.hour.from_now
end
end
【讨论】:
您可以捕获验证引发的异常。如果您在需要机械师之后在您的 spec_helper 中需要以下代码。要使用它,您可以添加一个 false 作为 #make 的第一个参数。
module Machinist
module ActiveRecordExtensions
module ClassMethods
def make_with_skip_validation(*args, &block)
validate = !(!args.pop if ( (args.first == true) || (args.first == false) ))
begin
make_without_skip_validation(*args, &block)
rescue ActiveRecord::RecordInvalid => invalid
if validate
raise invalid
else
invalid.record.save(false)
end
end
end
alias_method_chain :make, :skip_validation
end
end
end
【讨论】: