# Appropriately unit testing my models?

**URL:** <https://www.ruby-forum.com/t/appropriately-unit-testing-my-models/116052>\
**Category:** Rails\
**Created:** [October 1, 2007, 10:36pm UTC](https://www.ruby-forum.com/t/appropriately-unit-testing-my-models/116052 "2007-10-01T22:36:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![matt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a6a055/32.png) [@matt](https://www.ruby-forum.com/u/matt)\
**Post date:** [October 1, 2007, 10:36pm UTC](https://www.ruby-forum.com/t/appropriately-unit-testing-my-models/116052/1 "2007-10-01T22:36:35Z")

</div>

Can anyone point me towards a good resource on appropriately testing all  
the fields in a given model? Or perhaps give some advice.

For example, this test below is for a model with only a single column,  
but when I add a new column (a date field for example), how would I  
extend the test to cover both the body and date column of the model?

def test\_that\_status\_note\_body\_is\_valid  
note = Note.new  
# Empty body field  
assert !note.valid?  
assert note.errors.invalid?(:body)  
note.body = nil  
# Nil body field  
assert !note.valid?  
assert note.errors.invalid?(:body)  
note.body = “Testing body that should pass”  
# Correct body field  
assert note.valid?  
assert !note.errors.invalid?(:body)  
end

Would I create a new test called “test\_that\_date\_is\_valid” and only test  
against that or would I create tests that build instances of “Note” that  
contain as many test cases as it would take to test against every case?  
(which seems correct but when I think about how many tests would be  
involved for a model with even 5 columns it then seems to look not so  
correct)

I appreciate the responses, thanks!

---

<div class="post-metadata">

**Author:** ![matt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a6a055/32.png) [@matt](https://www.ruby-forum.com/u/matt)\
**Post date:** [October 2, 2007, 8:29am UTC](https://www.ruby-forum.com/t/appropriately-unit-testing-my-models/116052/2 "2007-10-02T08:29:34Z")

</div>

Matthew W. wrote:

> ```
> assert !note.valid?
> 
> ```
> 
> Would I create a new test called “test\_that\_date\_is\_valid” and only test  
> against that or would I create tests that build instances of “Note” that  
> contain as many test cases as it would take to test against every case?  
> (which seems correct but when I think about how many tests would be  
> involved for a model with even 5 columns it then seems to look not so  
> correct)
> 
> I appreciate the responses, thanks!

Maybe you’re can use a generic new method - something like:

def test\_status\_for\_something  
note = new\_note(:body =\> nil)  
…  
end

def new\_note(options)  
Note.new({:body =\> “Default body”, :header =\> “Default header”, :date  
=\> Date.today}.merge(options))  
end

Btw, I suggest that you split your testcases into smaller pieces, the  
above could be split into test\_body\_should\_be\_invalid\_when\_nil,  
test\_body\_should\_be\_invalid\_when\_empty\_string,  
test\_body\_should\_be\_valid\_when\_nonempty\_string.

Makes it easier to spot the problem when a test breaks.

–  
Cheers,

- Jacob A.

---

<div class="post-metadata">

**Author:** ![matt](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a6a055/32.png) [@matt](https://www.ruby-forum.com/u/matt)\
**Post date:** [October 3, 2007, 7:11am UTC](https://www.ruby-forum.com/t/appropriately-unit-testing-my-models/116052/3 "2007-10-03T07:11:15Z")

</div>

Try something like

class TestModel \< Test::Unit::TestCase  
def setup  
@model\_instance = Model.new  
end

## add here whatever you can think as empty value

def test\_should\_not\_body\_be\_empty  
assert\_error\_on @model\_instance, :body, :body =\> nil  
assert\_error\_on @model\_instance, :body, :body =\> “”  
end

# TODO: clean up this to use the first key of values hash as field

def assert\_error\_on(model, field, values = {})  
# there is no assert here cuz others field may have errors  
# and the idea is test one thing at time.  
model.valid?  
assert not model.errors[field].nil?  
end

# TODO: clean up this to use the first key of values hash as field

def assert\_no\_errors\_on(model, field, values = {})  
# there is no assert here cuz others field may have errors  
# and the idea is test one thing at time.  
model.valid?  
assert model.errors[field].nil?  
end  
end

Try to keep your tests clean, do one thing at time, and reflect that  
thing  
in the test name. And add as many test you need. Always remember  
that Test Cases are classes so add helper method to avoid repetitive  
tasks  
is not only good, its a must.

With this idea in mind test something like this:

class Model \< ActiveRecord::Base  
validates\_presence\_of :name  
validates\_length\_of :name, :in =\> 4…128  
validates\_uniqueness\_of :name  
end

will take at least one test per validation, but you probably wrote the  
tests first right? 😛

On Oct 1, 3:36 pm, Matthew W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
