# Unit test model validations

**URL:** <https://www.ruby-forum.com/t/unit-test-model-validations/162524>\
**Category:** Rails\
**Created:** [March 10, 2009, 9:14pm UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524 "2009-03-10T21:14:31Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 10, 2009, 9:14pm UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/1 "2009-03-10T21:14:31Z")

</div>

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 = “removed\_email\_address@domain.invalid”  
assert\_match(regex, @netronix.email)  
@netronix.email = “removed\_email\_address@domain.invalid”  
assert\_match(regex, @netronix.email)  
@netronix.email = “removed\_email\_address@domain.invalid”  
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:

1. 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’]:  
 is not true.

Model:  
validates\_presence\_of :name

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

1. 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’]:  
 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

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 11, 2009, 2:30am UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/2 "2009-03-11T02:30:29Z")

</div>

Michael R. wrote:

> ```
> 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
> 
> ```

Access looks like a separate table with a type.

How about, instead of retrofitting tests to existing features, you  
test-first  
the existence and behavior of this new type? Then test-first the  
database  
migration that copies your production data into it…

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 11, 2009, 12:09pm UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/3 "2009-03-11T12:09:44Z")

</div>

Hi Philip

wel I started out by trying to create my tests first, but I just got  
stuck so I decided to write the model validations.

Thats my biggest problem at the moment, I have never developed through  
TDD.  
And the main problem isn’t realy whether to develop or test first, but  
how to build my tests.

The logic of my tests has to be wrong, becouse eather way, they fail.

Any help is welcome.

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 12, 2009, 12:50am UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/4 "2009-03-12T00:50:47Z")

</div>

Colin L. wrote:

> I suggest starting with a very simple test and get that working first.  
> Use the debugger to find out what is going wrong if you cannot get it to  
> behave correctly.

Further, if you cannot _briefly_ get the test working, comment it out  
and write  
a simpler test, maybe on another feature.

Test the models first, for example.

The goal here is breadth-first, not depth first. The more tests you  
write, the  
more “muscle memory” you develop, and the easier new tests get. You  
might come  
back to this validation problem, for example, and just knock it out  
easily…

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 11, 2009, 2:40pm UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/5 "2009-03-11T14:40:01Z")

</div>

I suggest starting with a very simple test and get that working first.  
Use  
the debugger to find out what is going wrong if you cannot get it to  
behave  
correctly.

2009/3/11 Michael R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 12, 2009, 9:09am UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/6 "2009-03-12T09:09:37Z")

</div>

Hi guys.

I’ve been working on my skills the last couple of days. I have shown  
some improvements but as Colin stated, it is not something that you  
develop over night. It takes time and practice. But I notice that I’m  
making progress (maybe less then I expected, but still 🙂 ).

Brien, thanks for the input. I’m glad to see all the good work people  
make with writing information for newcomers.

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 12, 2009, 4:16am UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/7 "2009-03-12T04:16:41Z")

</div>

Michael:

In October, I gave a quick intro to Rails with test-driven development  
at a local code camp. I distributed a PDF to the group that walks a  
newcomer through test-first development. Perhaps it would help you get  
a handle on how to get started.

This link contains a link to the PDF as well as a link to the finished  
project on github.

[http://www.napcsweb.com/blog/index.php?s=code+camp&Submit=Search](http://www.napcsweb.com/blog/index.php?s=code+camp&Submit=Search)

Hope it helps. If you have questions, feel free to hit me up directly 🙂

On Wed, Mar 11, 2009 at 6:09 AM, Michael R.

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 12, 2009, 9:14am UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/8 "2009-03-12T09:14:07Z")

</div>

Hi, (sorry for the double post).

I’ve been working on some standard methods to test model validations.

At this point, I can test on these validations:

- validates\_presence\_of
- validates\_length\_of
- validates\_format\_of
- validates\_numericality\_of

But how do you test on the rest of validations if there is a way:

- validates\_uniqueness\_of
- validates\_confirmation\_of
- validates\_acceptance\_of
- validates\_associated
- validates\_exclusion\_of
- validates\_inclusion\_of
- validates\_each

---

<div class="post-metadata">

**Author:** ![roa](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8e7dd6/32.png) [@roa](https://www.ruby-forum.com/u/roa)\
**Post date:** [March 13, 2009, 8:24pm UTC](https://www.ruby-forum.com/t/unit-test-model-validations/162524/9 "2009-03-13T20:24:58Z")

</div>

Hi,

How do you validate booleans? Normally, I validate them through

validates\_inclusion\_of :is\_root, :in =\> [false, true]

But when I test the :is\_root attribute against a string, it passes. Here  
are some examples:

passes my test =\> [0, 1, true, false] (they should pass right?)  
don’t pass =\> [nil, ‘’, ’ '] (they shouldn’t pass, so test is still ok)

passes my test =\> [‘this is not valid’ ,-1, 1.30 ,2, 10], but they  
shouldn’t. Am I overlooking something, or is there still a bug in Rails  
2.3 RC2?
