i cant code
i cant code

Reputation: 343

Rails - How to test validate_with

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

Answers (1)

max
max

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

Related Questions