自定义验证器测试 - 包含错误?
Custom Validator Test - Contains Errors?
在我的 rails 项目中编写了一个自定义验证器,并想编写一个测试 nil
何时被传递到记录中。
验证者代码
class FutureValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value == nil
record.errors[attribute] << "can't be nil"
elsif value <= Time.now
record.errors[attribute] << (options[:message] || "can't be in the past!")
end
end
end
可能的测试
test "future validator rejects nil values" do
@obj.future = nil
assert_includes @obj.errors
end
我不仅想编写一个测试来检查 assert_not @obj.valid?
,而且还想实际证明错误消息正在被传回。如果这要求太多,我会满足于知道错误消息返回但目前我的测试不工作。
正在返回
ArgumentError: wrong number of arguments (1 for 2..3)
更新
接近绿色测试
test "future validator rejects nil values" do
@obj.future = nil
@obj.valid?
assert_includes @obj.errors.messages, {future: ["can't be nil"]}
end
回来了
FutureValidatorTest#test_future_validator_rejects_nil_values [/Users/rwdonnard/WorkSpace/charter-pay-api/test/models/future_validator_test.rb:42]:
Expected {:future=>["can't be nil"]} to include {:future=>["can't be nil"]}.
问题似乎是您测试 class 的方式,并且很可能是 assert_includes
引发的异常。 assert_includes
需要至少 2 个参数,第一个是集合,第二个是您希望包含的对象,在您的情况下分别是错误数组和您期望的错误。如果你不填充 @obj.errors
集合,你的测试也会失败,这需要调用 @obj.valid?
您的测试应如下所示:
test "future validator rejects nil values" do
@obj.future = nil
@obj.valid?
assert_includes @obj.errors.messages, { future: ["can't be nil"] }
end
如果 future.nil?
无论是否进行了其他验证,您都可以通过这种方式确保您的模型无效。
我还建议您不要在您的自定义验证器中检查是否存在,因为 Rails 已经为此提供了一种方法。你可以让你的验证器看起来像这样:
class FutureValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value <= Time.now
record.errors[attribute] << (options[:message] || "can't be in the past!")
end
end
end
并像这样在您的模型中设置验证:
class SomeClass < ActiveRecord::Base
validates :future, presence: true, future: true
end
您还可以简化测试,例如:
test "is invalid with nil future date" do
@obj.future = nil
@obj.valid?
assert_includes @obj.errors.messages[:future], "can't be nil"
end
test "future validator rejects past dates" do
@obj.future = Date.new(1987, 1, 1)
@obj.valid?
assert_includes @obj.errors.messages[:future], "can't be in the past!"
end
在我的 rails 项目中编写了一个自定义验证器,并想编写一个测试 nil
何时被传递到记录中。
验证者代码
class FutureValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value == nil
record.errors[attribute] << "can't be nil"
elsif value <= Time.now
record.errors[attribute] << (options[:message] || "can't be in the past!")
end
end
end
可能的测试
test "future validator rejects nil values" do
@obj.future = nil
assert_includes @obj.errors
end
我不仅想编写一个测试来检查 assert_not @obj.valid?
,而且还想实际证明错误消息正在被传回。如果这要求太多,我会满足于知道错误消息返回但目前我的测试不工作。
正在返回
ArgumentError: wrong number of arguments (1 for 2..3)
更新 接近绿色测试
test "future validator rejects nil values" do
@obj.future = nil
@obj.valid?
assert_includes @obj.errors.messages, {future: ["can't be nil"]}
end
回来了
FutureValidatorTest#test_future_validator_rejects_nil_values [/Users/rwdonnard/WorkSpace/charter-pay-api/test/models/future_validator_test.rb:42]: Expected {:future=>["can't be nil"]} to include {:future=>["can't be nil"]}.
问题似乎是您测试 class 的方式,并且很可能是 assert_includes
引发的异常。 assert_includes
需要至少 2 个参数,第一个是集合,第二个是您希望包含的对象,在您的情况下分别是错误数组和您期望的错误。如果你不填充 @obj.errors
集合,你的测试也会失败,这需要调用 @obj.valid?
您的测试应如下所示:
test "future validator rejects nil values" do
@obj.future = nil
@obj.valid?
assert_includes @obj.errors.messages, { future: ["can't be nil"] }
end
如果 future.nil?
无论是否进行了其他验证,您都可以通过这种方式确保您的模型无效。
我还建议您不要在您的自定义验证器中检查是否存在,因为 Rails 已经为此提供了一种方法。你可以让你的验证器看起来像这样:
class FutureValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if value <= Time.now
record.errors[attribute] << (options[:message] || "can't be in the past!")
end
end
end
并像这样在您的模型中设置验证:
class SomeClass < ActiveRecord::Base
validates :future, presence: true, future: true
end
您还可以简化测试,例如:
test "is invalid with nil future date" do
@obj.future = nil
@obj.valid?
assert_includes @obj.errors.messages[:future], "can't be nil"
end
test "future validator rejects past dates" do
@obj.future = Date.new(1987, 1, 1)
@obj.valid?
assert_includes @obj.errors.messages[:future], "can't be in the past!"
end