[rspec-users] How far to go with ActiveRecord unit tests without hitting the database?
mailing_lists at railsnewbie.com
Sun Sep 16 13:59:25 EDT 2007
On Sep 16, 2007, at 1:20 AM, David James wrote:
> I'm currently try to push my limits a little bit with some of my
> unit testing -- trying to avoid saving ActiveRecord objects to the
> database and take advantage of mock/stub objects.
> How far should I expect to get in this direction? From what I can
> tell, ActiveRecord seems to fight me when it comes to
> associations. In other words, many associations seem to require
> database queries.
> Have others had success in mocking/stubbing associations? In
> particular, have you had luck with has_many :through?
I would highly suggest taking a look at Jay Fields blog. The
examples use Test::Unit, but that shouldn't discourage you :). In
one of his posts he stubs/mocks out the class used for a database
column in ActiveRecord (ActiveRecord::ConnectionAdapter::Column).
I, personally, though, prefer to go the opposite way. Integration
Testing and Unit Testing are on a continuum, and in my opinion, the
only advantage of going the Jay Field's way (that is, the traditional
mocks/stubs approach - this is the one end of the continuum) is
speed. The truth is that Rails was not developed by a BDD'er, and
the coupling is too tight. When you test rails the way you would
test anything else, you'll soon realize how tight this coupling is,
because you will spend more time debugging rails then debugging your
Just as an example, the other day I had a method call in an
ActiveRecord class which did something like this:
and I had the following expectation:
Tag.should_receive(:create).with(:name => "Summer")
So where was my test failing? It wasn't in the logic of *my* code.
It was in how ActiveRecord dealt with this dynamic finder. The docs
Tag.find_or_create_by_name("Summer") # equal to Tag.create(:name
So I ran my debugger. Guess what! The call was to Tag.create("name"
=> "Summer"), not Tag.create(:name => "Summer"). (The difference was
that "name" was a string, not a symbol).
So - if you can afford to spend time debugging the internals of rails
(or if you know rails inside and out) , then yes - go right ahead and
have incredibly speedy unit tests. But otherwise, what exactly are
Sorry for the rant,
More information about the rspec-users