[rspec-users] Keeping unit tests from hitting the DB
dchelimsky at gmail.com
Fri Aug 24 12:58:36 EDT 2007
On 8/24/07, Jim Deville <james.deville at gmail.com> wrote:
> On Aug 23, 2007, at 9:48 PM, Pat Maddox wrote:
> > On 8/23/07, Jim Deville <james.deville at gmail.com> wrote:
> >>> As far as model specs go...I've been toying with the idea of
> >>> splitting
> >>> up non-db-reliant behavior specs from the specs that do require the
> >>> database. When you want to specify behavior you can just stub
> >>> out the
> >>> columns (because AR does try to hit the db to find the column info).
> >>> Obviously for things where you need to hit the db, such as custom
> >>> finders and such, you should use a real db. Kent Beck proposed
> >>> writing a mock db interface that expects SQL queries but I
> >>> thoroughly
> >>> hate that idea.
> >> I'm wondering why custom finders need to hit the database? Mocking
> >> out the columns method (as suggested by the articles) should work
> >> just as well for custom finders as it would for AR finders. Am I
> >> missing something?
> >> Jim
> > If I've got something like
> > def find_recent(limit = 5)
> > find :all, :order => "created_at DESC", :limit => limit
> > end
> > I think it's better to just create 6 records and make sure it returns
> > the proper 5. Then write another spec that only gets 3.
> I understand this, but overriding the Columns method, as suggested by
> Fields and Manges, should take care of this without hitting the DB.
> It's not checking the validity of the SQL, its using the columns
> method to return your result from fixtures without hitting the DB.
> > I suppose you could use a mock db that ensures that the SQL is
> > valid...but that seems brittle. Also at some point you have to ensure
> > that the generated SQL actually works (by running it). Might as well
> > do that in the spec itself. Also that's a better way because the
> Agreed, in some cases. In this case, testing the proper SQL feels
> like testing AR's implementation. If this was a find_by_sql method, I
> would completely agree with you here.
> > behavior you want in this case is for it to find the proper records,
> > not to generate some particular SQL string.
Well - there are two schools of thought on this. At a system test
level, there is no argument. However, at the object level, since this
object is interacting with the database, that's its behaviour. If you
accept that, then generating the correct SQL string is no different
than any other mock expectation.
FYI - I tried using the unit_record gem and there are some changes
required in rspec to make it work, but they are trivial and it works
great. The only trick is that the prevention of DB access is global
per process, so you'd have to separate examples that hit the DB from
those that don't into two separate suites. I'll explore this
possibility and follow up.
> > Pat
> > _______________________________________________
> > rspec-users mailing list
> > rspec-users at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/rspec-users
> rspec-users mailing list
> rspec-users at rubyforge.org
More information about the rspec-users