[rspec-users] Mocks? Really?

Pat Maddox pergesu at gmail.com
Wed Dec 26 15:23:44 EST 2007

On Dec 23, 2007 2:27 PM, Zach Dennis <zach.dennis at gmail.com> wrote:
> I know the questioned are directed towards Dan so I hope you don't me
> chiming in. My comments are inline.

Thanks a lot for your comments, I really appreciate them.  I've been
dying to respond to this for the past several days, but haven't had
internet access.

> On Dec 15, 2007 2:17 AM, Pat Maddox <pergesu at gmail.com> wrote:
> >
> > On Dec 8, 2007 4:06 AM, Dan North <tastapod at gmail.com> wrote:
> > > I prefer the mantra "mock roles, not objects", in other words, mock things
> > > that have behaviour (services, components, resources, whatever your
> > > preferred term is) rather than stubbing out domain objects themselves. If
> > > you have to mock domain objects it's usually a smell that your domain
> > > implementation is too tightly coupled to some infrastructure.
> >
> > Assuming you could easily write Rails specs using the real domain
> > objects, but not hit the database, would you "never" mock domain
> > objects (where "never" means you deviate only in extraordinary
> > circumstances)?  I'm mostly curious in the interaction between
> > controller and model...if you use real models, then changes to the
> > model code could very well lead to failing controller specs, even
> > though the controller's logic is still correct.
> In Java you don't mock domain objects because you want to program
> toward an interface rather then a single concrete implementation.
> Conceptually this still applies in Ruby, but because of differences
> between the languages it isn't a 1 to 1 mapping in practice.

I must be misunderstanding you here, because you say you "don't mock
domain objects," and the rest of your email suggests that you mock
basically everything.


> > Do you try to test each
> > class in complete isolation, mocking its collaborators?
> Yes. The pattern I find I follow in testing is that objects whose job
> it is to coordinate or manage other objects (like controllers,
> presenters, managers, etc) are always tested in isolation.
> Interaction-based testing is the key here. These objects can be
> considered branch objects. They connect to other branches or to leaf
> node objects.
> Leaf node objects are the end of the line and they do the actual work.
> Here is where I use state based testing. I consider ActiveRecord
> models leaf nodes.

What about interactions between ActiveRecord objects.  If a User
has_many Subscriptions, do you mock out those interactions?  Would you
still mock them out if User and Subscription were PROs (plain Ruby
objects) and persistence were handled separately?

> > When you use
> > interaction-based tests, do you always leave those in place, or do you
> > substitute real objects as you implement them (and if so, do your
> > changes move to a more state-based style)?
> Leave the mocked out collaborators in place. An interaction based test
> verifies that the correct interaction takes place. As soon as you
> remove the mock and substitute it with a real object your test has
> become compromised. It's no longer verifying the correct interaction
> occurs, it now only makes sure your test doesn't die with a real
> object.

This leads to perhaps a more subtle case of my previous
question...ActiveRecord relies pretty heavily on the real classes of
objects.  To me, this means that it would make more sense to use mocks
if you didn't use AR, but use the real objects when you are using AR.
Again, this is only between model objects.  I agree that controller
specs should mock them all out.

> > I realize that's a ton of questions...I'd be very grateful (and
> > impressed!) if you took the time to answer any of them.  Also I'd love
> > to hear input from other people as well.
> >
> It's too bad we can't just stand at a whiteboard and talk this out.
> The answers to these questions could fill a book and email hardly does
> it justice to provide clear, coherent and complete answers. Not that
> my response are "answers" to your questions, but it's how I think
> about testing and TDD.

Thanks again for your thoughtful reply.  Looking forward to hearing a
little bit more.


More information about the rspec-users mailing list