I was working on an application and needed to test the models, which is a pretty normal practice.  I had to repeat validation tests for each field and each model resulting in lots of duplicated test code.  So, I’m going to share my solution to this problem, which will help us avoid repeating similar validation tests for each model. 

I’m using Ruby 2.3.0, Rails 4.2.4.  And Minitest and FactoryGirl in my test suite.  I had this test written for a Site Model like:

Too much code for a simple feature to test, eh?  Right.  Imagine if you have to repeat it in all models for all the fields you want to validation. 

I don’t know if there are any Gems to DRY this thing out or not, as I didn’t bother to search for existing solutions to this problem.  Instead, I started using the Ruby’s OO goodness to carve out a light solution of my own.  And this is what I came up with:

Yes, that’s it :).  That’s all it takes to test model validations.  Now we have class macros for our test classes just like we have in our actual models for declaring validations.  That’s almost half the code we previously had to write to achieve the same thing.  Imagine using this in all your model tests, which hopefully will save you hundreds of lines of code and copy/paste effort.  Let’s run the test again to ensure that everything is working as it was before:

Boom!  Everything works as expected, but is much cleaner and convenient.  This makes life easier for model validation testing. 

I don’t know how deep I should go into explaining my implementation and how many of you will be interested to know how this implementation works.  So I’m just gonna wrap this up here and if any questions arise, I’ll be glad to answer them in the comments section or any other communication medium. 

One thing I feel would benefit from a bit of explanation is this macro/line:

test_validates_uniqueness_of FactoryGirl.create(:site), :host

This macro validates the uniqueness of a model field.  The first argument is the persisted instance of the model from which the field will be duplicated.  After that first argument, you can provide any number of arguments as fields on which you want to validate uniqueness. 

That’s it.  Looking forward to your comments and questions.  I really hope this helps you in some way.