[rspec-users] More on collection proxies

David Chelimsky dchelimsky at gmail.com
Wed Jan 24 01:26:19 EST 2007


On 1/21/07, Jay Levitt <lists-rspec at shopwatch.org> wrote:
> David Chelimsky wrote:
> > On 1/21/07, Jay Levitt <lists-rspec at shopwatch.org> wrote:
> >> I've got a question similar to Francois's.  I'm writing a to-do-like
> >> application, where each Task has a number of Events, consisting of
> >> event.date and event.status.  I want to see how long it's been since the
> >> Task was last completed.  So:
>
> [snip]
>
> >> This smells a bit.  I could separate part of completed_days_ago into
> >> last_completed_on(date), but no matter how I slice it I still end up
> >> mocking Task.cells for some routine.  Suggestions?
> >
> > The next question is, why are we passing in the date? We want to how
> > many days have passed since it was completed, not how many days
> > between completion and some arbitrary date.
>
> Actually, we want the latter - but of course you couldn't tell that from
> my method name!  The tasks are repeating, and this app fills in a
> spreadsheet-like series of cells, one per day, with various colors,
> depending on how often you're completing a task.  So we actually need to
> check the task's status on any given day.
>
> [..]
> >     event_stub = Struct.new(:date,
> > :status).new(Time.parse("2001-02-03"), "completed")
> >     @task.stub!(:events).and_return([event_stub])
> [..]
>
> You don't mind stubbing the association proxy as a struct?  That was my
> real question; it seems to lead down a messy road of trying to stub
> every ActiveRecord method.  On the one hand, it seems like BDD says I
> should stub or mock any object other than the one under test.  On the
> other, since I'm still in the models realm, maybe it's okay to use
> fixtures to represent the model relations.  Or maybe there's a third way.

I'm kind of on the fence on this topic. I've been of the mindset that
since models are so tightly bound to AR that it's more trouble than
its worth to try and break that dependency. Because I mock models in
all of my controller and view specs, I'm only hitting the db for the
things that are interesting about models.

Recently, I read a post from Jay Fields where he talks about what
amounts to mocking out the loading of a file. So if you want to spec
that User should validate presence of email, you do this:

User.should_receive(:validates_presence_of).with(:email)
load "${RAILS_ROOT}/app/models/user.rb"

Odd, huh? It wouldn't be if the API for AR was like this:

@model_registry.should_receive(:validate_presence_of).with(User, :email)
User.register(@model_registry)

Essentially, loading the file IS the entry point to the AR API.
Interesting point of view, no?

I like two things about this:
clear specs
fast specs

I can write all my validation specs in two lines each. No models to
create. No database to connect to. Pretty awesome.

So, no, I don't mind mocking the proxy in model specs, though I would
always try to avoid that seeping out to the controllers and views.

That helpful?

Cheers,
David


>
> Jay
>
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>


More information about the rspec-users mailing list