[rspec-users] We can't 100% remove our unit tests from the database, can we?
aslak hellesoy
aslak.hellesoy at gmail.com
Thu Feb 22 16:42:14 EST 2007
On 2/22/07, Pat Maddox <pergesu at gmail.com> wrote:
> I hope this isn't too rambly. This is sort of a brain dump of a
> subject I've been thinking about for months as I've used RSpec.
>
> Let's say we've got a simple query method, that will find all the
> users in the DB older than 18. Our model could look like
>
> class User < ActiveRecord::Base
> def self.find_older_than(age)
> find :all, :conditions => ["age > ?", age]
> end
> end
>
> What would our spec look like?
>
> specify "should find all users over the given age" do
> User.should_receive(:find).with(:all, :conditions => ["age > ?", 18])
> User.find_older_than 18
> end
>
> I don't know about you, but to me that sucks. There is no TDD rhythm
> there. We write a failing spec, but it's a fairly complex spec. On
> top of that we've basically implemented the method from within the
> spec. That's not TDD.
>
> We also can't refactor. Let's say that at some point we decided to
> change the method to
>
> def User.find_older_than(age)
> find(:all).select {|u| u.age > age }
> end
>
> Our spec would break, even though the semantics of
> User.find_older_than hasn't changed.
>
> Okay, so it's just a crappy spec. But how do we change it? Lots of
> people suggest stubbing out DB calls. There's no sense in testing the
> same thing over and over - namely that you have a connection and your
> ORM tool is working correctly.
>
> I'm beginning to think that most of the time, you don't want to use a
> test DB at all. When you're testing an AR model, just use an
> in-memory record and stub any associations you need. But when you do
> do something that interacts with the database - like doing a custom
> find - you need to use the database to make sure that you're getting
> the right results. Whether you use fixtures or create some records in
> the setup method, you have to actually hit the db.
>
> Let me know what you think. I'm completely open to the idea that I've
> missed something pathetically obvious.
>
Only mock AR when you're speccing code that *interacts* with AR
(controllers and views).
Don't mock AR in specs for AR subclasses - let them go against a real database.
Don't mock APIs you don't own.
See http://www.jmock.org/oopsla2004.pdf for more on this
HTH,
Aslak
> Pat
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
More information about the rspec-users
mailing list