Hi,

since I want to improve my Rails skills, I decided to start using the
Rails testing framework. But I find it a bit hard to start testing model
validations. Some of my tests don't pass, but I know they must, since I
have added the validation in the model.

Here is an example:

The migration:

    create_table :clients do |t|
      t.string  'name',             :null => false
      t.string  'address',          :null => false
      t.string  'zip',              :null => false
      t.string  'city',             :null => false
      t.string  'country',          :null => false
      t.string  'phone',            :null => true
      t.string  'fax',              :null => true
      t.string  'email',            :null => false
      t.integer 'status',           :null => false
      t.boolean 'is_root',          :null => false, :default => false
      t.boolean 'access_crm',       :null => false, :default => false
      t.boolean 'access_project',   :null => false, :default => false
      t.boolean 'access_dmail',     :null => false, :default => false
      t.boolean 'access_financial', :null => false, :default => false
      t.timestamps
    end
Extension in test_helper.rb:

  def assert_presence_required(object, field)
      # Test that the initial object is valid
      assert object.valid?

      # Test that it becomes invalid by removing the field
      temp = object.send(field)
      object.send("#{field}=", nil)
      assert object.valid?
      assert(object.errors.invalid?(field), "#{field} is required")

      # Make object valid again
      object.send("#{field}=", temp)
    end

    def assert_required_length(object, field, minlength, maxlength)
        dup_object = object.clone

        if(minlength)
          # Invalid at minlength-1
          dup_object.send("#{field}=", "a"*(minlength-1))
          assert dup_object.valid?
          assert(dup_object.errors.invalid?(field), "#{field} has a
minimum length of #{minlength} character(s)")

          # Valid at minlength
          dup_object.send("#{field}=", "a"*minlength)
          assert dup_object.valid?

          # Valid at minlength+1
          dup_object.send("#{field}=", "a"*(minlength+1))
          assert dup_object.valid?
        end

        if(maxlength)
          # Valid at maxlength-1
          dup_object.send("#{field}=", "a"*(maxlength-1))
          assert dup_object.valid?

          # Valid at maxlength
          dup_object.send("#{field}=", "a"*maxlength)
          assert dup_object.valid?

          # Invalid at maxlength+1
          dup_object.send("#{field}=", "a"*(maxlength+1))
          assert dup_object.valid?
          assert(dup_object.errors.invalid?(field), "#{field} has a
maximum length of #{maxlength} character(s)")
        end
    end

The unit test:

  def setup
    @netronix = clients(:netronix)
  end

  def test_validates_presence_of
    assert_presence_required(@netronix, :name)
    assert_presence_required(@netronix, :address)
    assert_presence_required(@netronix, :zip)
    assert_presence_required(@netronix, :city)
    assert_presence_required(@netronix, :country)
    assert_presence_required(@netronix, :email)
    assert_presence_required(@netronix, :status)
    assert_presence_required(@netronix, :is_root)
    assert_presence_required(@netronix, :access_crm)
    assert_presence_required(@netronix, :access_project)
    assert_presence_required(@netronix, :access_dmail)
    assert_presence_required(@netronix, :access_financial)
  end

  def test_validates_length_of
    assert_required_length(@netronix, :name, false, 255)
    assert_required_length(@netronix, :address, false, 255)
    assert_required_length(@netronix, :zip, false, 255)
    assert_required_length(@netronix, :city, false, 255)
    assert_required_length(@netronix, :country, false, 255)
    assert_required_length(@netronix, :email, false, 255)
  end

  def test_validates_format_of
    regex = /^[A-Z0-9._%-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i
    assert_match(regex, @netronix.email)
    tmp = @netronix.email
    @netronix.email = "[email protected]"
    assert_match(regex, @netronix.email)
    @netronix.email = "[email protected]"
    assert_match(regex, @netronix.email)
    @netronix.email = "[email protected]"
    assert_match(regex, @netronix.email)
    @netronix.email = tmp
  end

  def test_validates_uniqueness_of
    user = Client.new(:name => @netronix.name)
    user.valid?
    assert_not_nil user.errors.on(:name)

    user = Client.new(:email => @netronix.email)
    user.valid?
    assert_not_nil user.errors.on(:email)

  end

I know there are some things wrong with my test, but I don't know what.
The first thing wrong is the validate_length_of helper. For some reason,
it throws a failure even when the validation is filled in the model:

  3) Failure:
test_validates_presence_of(ClientTest)
    [/test/test_helper.rb:45:in `assert_presence_required'
     /test/unit/client_test.rb:10:in `test_validates_presence_of']:
<false> is not true.

Model:
  validates_presence_of :name

Second problem is the check of the required length. Also this test
fails:

  2) Failure:
test_validates_length_of(ClientTest)
    [/test/test_helper.rb:81:in `assert_required_length'
     /test/unit/client_test.rb:25:in `test_validates_length_of']:
<false> is not true.

Model:
  validates_length_of :name,  :maximum => 255

then the email format is completely wrong. It test my regex against a
string, but doesn't realy validate my model validations. same story with
the uniqueness, doesn't work, and how do you test against a uniqueness
over 2 fields?

I have searched the net on more info and also checked out the new rails
guids, but they all cover just the basics and not don't realy go into
how to test you model validations.

I hope their is an expert around here who can help me furter on how to
test my model validations.

Thank you in advance
-- 
Posted via http://www.ruby-forum.com/.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to