Mock/Stub police for your Ruby/Rails unit tests
October 3rd, 2007
I just wrote a simple unit test which indirectly resulted in calling create for the AR object.
The problem is that I don’t want to create objects in my unit tests – in particular, I try to avoid hitting the database (or disk, or network for that matter) as much as possible, keeping my unit tests fast. Sure, actual calls to create, save etc. need to be tested too, but I’ll leave those for the integration tests.
So, I wanted to make a simple reminder which nags to me whenever I call create for AR objects indirectly or directly, but I only want those alerts when running stuff inside test/unit directory. I modified
ActiveRecord::Base#create slightly to warn the user about using it, and placed it in the test/unit directory by naming it so that it is loaded first (aardvardks_automatic_insinuation_for_spline_reticulation_test.rb would work just fine):
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class ActiveRecord::Base @@_nagged_already = false alias_method :orig_create, :create def create(*args) if not @@_nagged_already warn "\nPlease avoid calling ActiveRecord#create in unit tests (mock/stub stuff instead)" @@_nagged_already = true end orig_create(*args) end end |
Now, running rake test:units warns about use of create, but it doesn’t affect any other tests (like test:functionals or test:integration).
Alright, it’s a bit of a hack, but Works For Me™.
1 Response to “Mock/Stub police for your Ruby/Rails unit tests”
Sorry, comments are closed for this article.

October 4th, 2007 at 05:43
You might want to see where the code was called from. More nagging version showing the call lines is attached below:
WARNING_TEMPLATE = "\n*** %s\n*** Please avoid calling ActiveRecord#create in unit tests (mock/stub stuff instead)" class ActiveRecord::Base alias_method :orig_create, :create def create(*args) warn(WARNING_TEMPLATE % caller(0).select { |l| l =~ /test\/unit/ }.join("\n")) orig_create(*args) end end