[rspec-users] Why stop using mock_model in scaffold controller spec?

David Chelimsky dchelimsky at gmail.com
Thu Mar 29 11:39:35 UTC 2012

On Tue, Mar 27, 2012 at 9:24 AM, Mike Mazur <mmazur at gmail.com> wrote:
> Hi,
> On Tue, Mar 27, 2012 at 22:10, Mike Mazur <mmazur at gmail.com> wrote:
>> In May last year, the controller specs generated with `rspec g
>> scaffold` were changed to use real model objects instead of
>> `mock_model`.
>> I'm curious why this change was made?
> As soon I sent this email off, I noticed this text in the template:
> # Compared to earlier versions of this generator, there is very limited use of
> # stubs and message expectations in this spec.  Stubs are only used when there
> # is no simpler way to get a handle on the object needed for the example.
> # Message expectations are only used when there is no simpler way to specify
> # that an instance is receiving a specific message.
> That explains things a bit, but I'm still curious!
> One might argue that the earlier approach (with `mock_model`) may be
> better for at least two reasons:
> - looser coupling between specs and models
> - faster spec execution (ie: don't have to create a real ActiveRecord instance)
> I imagine RSpec is treading the fine line between ideal "best
> practices (ie: minimize coupling) and being more pragmatic and easier
> to understand by the average developer. What's the current thinking on
> this topic?

It wasn't really a loose coupling with models, it was a loose coupling
with the underlying data. It was still very tightly coupled to
ActiveRecord APIs (all, find, etc) because the generated controller
code is coupled to those APIs.

In rails-2, you could stub Model.find, and if you added constraints to
find the specs would still pass because you were still using find. In
rails-3, additional constraints are added via ARel APIs, which don't
end up going through find, so you have to change all the specs when
you change the implementation. This created additional friction which
was annoying to people who understood what was going on, and confusing
for people who didn't.

In terms of the speed benefit, I do think that has merit and I stub
model APIs all the time, but they are domain-specific APIs, not
ActiveRecord APIs (most of the time). e.g. rather than stubbing
Article.where("date >= ?", Date.today - 1.week) I'll stub
Article.recent and call that from the controller. This, however, is
not something that a generator can do for you since it doesn't know
your domain.


More information about the rspec-users mailing list