When/why/should I unit test validations?

I run into this question each time I add a validation to my model.

Should I add a unit test for that validation?

On the one hand, I've heard/read the philosophy: "Q: What should I test? A: Only the stuff you care about working".

On the other hand I've heard/read, "You don't need to test methods provided by Rails -- they are already tested by the test suite included with the framework."

If I put this in my model:

validates_uniqueness_of :name

Then I feel like I should write a unit test like test_name_should_be_unique. But then that feels like I'm testing the framework. If I've gone through the trouble of adding the validation to my model, then it feels like I should go through the trouble of testing the code I added to my model. Equivalently, if you're in the TDD/BDD driven camp, if I care about the behavior that the name should be unique, I should write a test in which I try to add 2 records with the same name field, verify the test fails, add the validation to my model, and verify the test passes.

At this point, I start to think... DRY. Why should I write substantially the same tests for every field in each model for which I care that the field is unique (or present, or has a numericality, etc...).

Are there test helper methods such as #test_uniqueness_of, or #test_presence_of? I've never seen such functions, which makes me think that they're not important or useful enough for anybody (other than myself) to have written and used. Since I have never had a good idea that wasn't replicated 100 times on the internet already, I tend to think these sort of helper functions aren't a good idea.

So I ask why not? What am I missing?

--wpd

You are right that everyone seems to disagree on this point. I think validating the data is one of the most critical parts of an application. I tend to validate at the db level and model level to ensure integrity (as the app is not necessarily the only point of entry to the db--psql prompt, another app, etc). If the application cannot reliably trust the data it is likely to be buggy.

With that said, I like to write tests for the validations. This is not because I don't trust the tests done by rails, but because I don't trust myself. I could misspell (mispell?) one of the validations, delete it accidently while I am refactoring, etc. With a few tests in place, the upfront effort is repaid, because I can be confident it is acting in the way I expect.

I haven't used helpers like you ask, but I imagine they exist.

Just my 2 cents

Andrew

Personally I like to test validations. I write my tests/specs first, so I write them for the validations that I think I should have.

Secondly because not all validations are as simple as validates_presence_of :foo, there's often other options, conditions or blocks involved. Those are often added as afterthoughts so you want to check they do whet you expect. And don't break things.

I also like to check that the validation failure gives me the correct message.

Patrick Doyle wrote:

I run into this question each time I add a validation to my model.

Should I add a unit test for that validation?

Yes.

On the one hand, I've heard/read the philosophy: "Q: What should I test? A: Only the stuff you care about working".

On the other hand I've heard/read, "You don't need to test methods provided by Rails -- they are already tested by the test suite included with the framework."

Correct. But you *do* have to test that you are using those methods correctly.

If I put this in my model:

validates_uniqueness_of :name

Then I feel like I should write a unit test like test_name_should_be_unique. But then that feels like I'm testing the framework.

No, you're testing your use of the framework -- after all, it would fail if you forgot to add the validation, no matter how well tested Rails is!

(And you should really be using RSpec, not Test::Unit.)

If I've gone through the trouble of adding the validation to my model, then it feels like I should go through the trouble of testing the code I added to my model.

Right! You don't have to test the framework code in detail, but you should test that you at least put it into your model.

Equivalently, if you're in the TDD/BDD driven camp, if I care about the behavior that the name should be unique, I should write a test in which I try to add 2 records with the same name field, verify the test fails, add the validation to my model, and verify the test passes.

Right! (I usually check valid? in circumstances like these.)

At this point, I start to think... DRY. Why should I write substantially the same tests for every field in each model for which I care that the field is unique (or present, or has a numericality, etc...).

Are there test helper methods such as #test_uniqueness_of, or #test_presence_of?

If there aren't, you could write them.

I've never seen such functions, which makes me think that they're not important or useful enough for anybody (other than myself) to have written and used. Since I have never had a good idea that wasn't replicated 100 times on the internet already, I tend to think these sort of helper functions aren't a good idea.

So you think that anything not already done is not worth doing? That means you'll never write any original code at all!

So I ask why not? What am I missing?

You're missing the point of writing tests. :slight_smile:

Or you're not missing anything except the fact that your instincts are correct in this case. Absolutely, test that you have the right validations in place.

--wpd

Best,