While refactoring some functional tests for a side project yesterday and came up with a simple but great pairing: mock_model with a side of Factories & Workers.
mock_model
is an RSpec helper that stubs out many ActiveRecord methods to limit (but not totally remove) calls to the database. It has the conceptual benefit of isolating your tests from the database, but the practical benefit is much faster tests.
But I always hated providing a list of attributes to mock_model
, like so:
negative_aged_user = mock_model(User, :name => 'Foo', :age => -42)
It just always seemed inelegant, because I only wanted to include attributes that were important to a specific test, but leaving out common attributes would create a cascading set of test failures. I actually really hate how much mocking and stubbing, in general, forces me to expose the internals of my code, rather than testing interfaces.
Anyway, yesterday I realized that Factories & Workers exposed a method valid_MODEL_attributes
along with create_MODEL
and build_MODEL
.
So now, instead of including all the attributes all the time, I can just do this:
mock_model(User, valid_user_attributes(:age => -42))
I’ve taken this a bit further, and have written a helper method, mock_user
, which pairs nicely with Factories & Workers’ create_user
and build_user
methods. Now I can use the same syntax for mocked models, or database-backed models. Yay!