Reputation: 343
I have the following model that has custom validation for a valid code.
class MyAd < ApplicationRecord
validates_with CodeValidator
end
and the following class:
class CodeValidator < ActiveModel::Validator
def validate(record)
code = record.ad_code
return if is_double_id?(code) || is_id?(code)
if code.blank? || code == 'NO_CODE'
record.errors[:base] << "A valid code is required."
end
end
def is_double_id?(code)
code.match(regex here)
end
def is_id?(code)
code.match(regex here)
end
end
How do I write a test for this? I am new to rails and have adopted this code so am a bit confused as to how to do it.
Here is what I started but from reading I am not sure how to test it. Does MyAd.new() force the validation to happen?
require 'test_helper'
class MyAd < ActiveSupport::TestCase
setup do
@ad = MyAd.new(ad_code: 894578945)
end
test 'it test code validity' do
#this is where i need help
end
Any help will be appreciated.
Upvotes: 0
Views: 305
Reputation: 101891
Just setup a valid / invalid model instance and call #valid?
to trigger the validations. You can then write assertions about the errors object.
require 'test_helper'
class MyAd < ActiveSupport::TestCase
test 'it does not allow a blank code' do
@ad = MyAd.new(code: '')
@ad.valid? # fires the validations
# @fixme your validator should actually be adding errors to :ad_code and not :base
assert_includes(@ad.errors[:base], 'A valid code is required.')
end
test 'it allows a valid code' do
@ad = MyAd.new(code: 'SOME VALID CODE')
@ad.valid?
refute_includes(@ad.errors[:base], 'A valid code is required.')
end
end
Don't test validations by:
# as popularized by the Rails tutorial book
assert(model.valid?)
refute(model.valid?)
This carpet bombing approach will test every validation on the model at once and your really just testing your test setup.
Does MyAd.new() force the validation to happen?
No. Validations are performed when you call #valid?
or the persistence methods like #save
, .create
and #update
.
Upvotes: 1