Wednesday, October 5, 2011

Rails 3 - unit testing validators with check validate reflection method

I don't know if this is to best practices or not (and I really don't give a shit -- this works great). Here's the idea:

model:

class Submission < ActiveRecord::Base
  validates_presence_of     :title 
  validates_presence_of     :first_name
  <snip>
end


I load some data in with a fixture to make the model valid.... blah blah

unit test:

require 'test_helper'

class SubmissionTest < ActiveSupport::TestCase
  def setup
    @one = submissions(:one)
  end
  test "empty title invalidates" do
    assert !check_validate(@one,"title")
  end
  
  test "empty first name invalidates" do
    assert !check_validate(@one,"first_name")
  end
 .....


Now the check_validate method, and the quick check method:


def check_validate(object,field)
    #Make sure object is valid
      assert_object_valid(object)
    #set old to objects value 
      old = object.send(field.to_sym)
    #send setter to object along with nil to blank it
      object.send("#{field}=".to_sym, nil)
    #set return value to boolean of valid? on object
      return_value = object.valid?
    #send setter to object for field with old value
      object.send("#{field}=".to_sym, old)
    #Make sure we leave the object valid when we're done
      assert_object_valid(object)
    #return the value
      return return_value
  end
    
  def assert_object_valid(object)
    assert object.valid?, "test entered with invalid object"
  end



It works great.. nice and DRY, this way I don't have to blank them all out, and put them all back.. ruby's reflection is a billion light years beyond any I've used for anything else ever. (Java? what?) I plan on modifying the check_validate to simplify other checks as well, and create my own library of test for common tasks. Maybe it already exists? I looked, and didn't find one.

~Nic

No comments: