I am a Sr. Software Developer at Oracle Cloud. The opinions expressed here are my own and not necessarily those of my employer.
Keeping our tests DRY
As we add more features to our applications we inevitably have to refactor existing code. At one point I had to introduce polymorphic relation to a model. Previously it was simply this with Mongoid and Ruby on Rails
Now we change it to:
We also need to do a small data migration with mongoid_rails_migrations.
Under the hood Rails uses author_id
and author_type
fields in Article
model. But this post is not about polymorphic relations (read more here).
After implementing this change we need to update article.user
to article.author
. And we need to change Rspec tests and FactoryGirl factories.
When I was doing this in my application I realized that while I changed a few model / controller (core code) files I had to change LOTS of test files. I had pretty decent coverage (over 80%) but maintaining the tests became quite time consuming. The cost of refactoring tests became greater than the cost of refactoring the application.
The most common reason I had to change my tests is because I was explicitly calling this in my tests:
Even though I created association in the factories:
The reason is I had to test methods on User
and Article
that expected specific instances and it was just too easy to create in the test (only one line) than to properly think through how to setup the factory. And I had numerous validations in my models that required data to be setup in a very specific manner.
One way to avoid this overhead when all we need is to save data to our DB is to do this:
Now data is persisted and we can test article
methods (especially if we don’t care about user
relationships).
A different technique to use stubs and doubles.
This is best applied with small modular classes that follow single responsibility principle.
I use these approaches selectively because while I want to test my code in isolation faking too many things can lead to problems of their own.
Another important lesson to ease the refactoring pain is following Law of Demeter but that’s for a different blog post.