Best Practices for Unit Testing the Model?

What are people's thoughts on unit testing in the model? I was
looking through the RoR manual[1] and it showed some examples of
testing CRUD operations. Does this make much sense? Aren't you just
testing ActiveRecord and Rails at this point?

If you are interested in testing your validation rules you could have
something like ...

assert @foo.validate

Why actually test the persistence to the database? When using Java
and Hibernate I would test the actual persistence but that was so I
could test the actual mapping configuration. I suppose with Rails you
can still check if the associations are mapped correctly (such that
they are actually persisted.)

What else should one test in models? Other then validation the other
good candidate seems to be class methods.

Just curious what people are doing....

Sean

[1] http://manuals.rubyonrails.com/read/chapter/27

schof wrote:

What else should one test in models? Other then validation the other
good candidate seems to be class methods.

I agree. I think some of that is just examples. In general I test my code, not the code my code depends on. I rely on other people to test their code (and if they are not testing enough then I might consider adding a test to their code but I would not add a test for their code in my testing). In the model things I test often:

* Complex validation (things like validates_confirmation_of again I rely on Rails to test that. I just test custom validation stuff)
* Custom finders. So if I have a "find_active" method that finds all active records I make sure an inactive record is not included.
* Custom Logic. So if I have a "mark_completed" method I make sure that updates the fields correctly

Basically I test the code that I wrote. If my code is just declarative and other code is actually implementing the functionality I don't usually test that.

Eric

Someone on the Seattle.rb mailing list pointed out what I thought was
a compelling and simple question for testing things like validations:

Does your test break if you remove the validation code?

The point isn't to test that Rails validations work - I think you're
right about not testing other people's code in that sense. But if you
can remove critical code from your model, and your test passes, then
your test isn't complete.

This probably came up in the context of a Heckle mutation tester discussion:

http://blog.zenspider.com/archives/2007/06/heckle_version_141_has_been_released.html

- James Moore

James Moore wrote:

schof wrote:

What else should one test in models? Other then validation the other
good candidate seems to be class methods.

CRUD.

Anything a user can do thru the GUI, a programmer can do, nearly the same way, with the models. Suppose that updating a customer record requires all the matching account records to change their state. If a user does this, they hit the Update button on their form (the U in CRUD), then they go to the account page, and all the records have a new status.

If a programmer does this (via a unit test, or the console), they call a method on the Model object with the same parameters as that form had. Then when they query account records, these all have the matching update.

Put another way, Controllers should have no business logic. They should not even intermediate between Model objects. All business logic should reside only in the Model.