
Mocks Aren't Stubs (2007) - backslash_16
http://martinfowler.com/articles/mocksArentStubs.html
======
dpark
I feel like this distinction is arbitrary and unintuitive. A mock is literally
just something that mimics something else. All "doubles" can be considered
mocks. Claiming that mocks _insist_ on call verification seems like a very
forced categorization. If there's value in this distinction, maybe we need new
terminology instead of asserting that everyone who's conflated "stubs" and
"mocks" for two decades is wrong.

As a side note, verifying call patterns makes for terrible, brittle tests that
cost far too much to maintain. This pattern is great for enforcing call
patterns that truly that matter for, e.g, performance reasons (no unexpected
cascade of DB calls), but is typically just a giant pain that provides little
to no value, because instead of testing that the code does the right thing,
you're testing that _it doesn 't change_.

~~~
gary_bernhardt
There are objects that demand to be interacted with; there are objects that
allow only certain predefined interactions; there are objects that allow any
interaction and record them all for later inspection; and there are objects
that are simple implementations of interfaces whose "real" implementation is
more complex. Each of these object types exists in practice, and each is
clearly an example of some larger category.

One group of people says "these should all be called mocks". Another group
says "these are mocks, stubs, spies, and fakes, respectively, and collectively
these are called test doubles". You can prefer the simplicity of calling them
all "mocks" (simplicity is nice) but that leaves you with no way to
distinguish between the types.

These categories seem like hair-splitting if you've written relatively few
tests using test doubles. Once you've written a few thousand, you start to
wish for even finer-grained distinctions. This is how basically everything
works as you get deeper into the details: you need words for the fine-grained
distinctions.

As far as I know, there has never been a competing set of terms. The only
major positions are "we should use [the words I mentioned above]", which is
mostly favored by those who have used a lot of doubles; and "we should not use
separate words at all", mostly favored by those who haven't used a lot of
doubles.

~~~
tatterdemalion
One of the things that programmers do that I find most frustrating is proclaim
that the definition of words that they use is the objectively correct
definition, and frame their entire discussion as an argument that other people
aren't using words correctly. Pick any term and the kind of argument comes to
mind - "type," "object," "metaprogramming," "dependency injection," "design
pattern," etc.

This article has a lot of good content about testing strategies, as well as an
introduction to some of the jargon used in a certain testing discourse, but
the argument is framed as telling you that _mocks aren 't stubs_, and you, the
reader, have been using these words incorrectly. But the reader has only been
using these words differently.

This is a very common pattern of behavior among programmers and I think it is
worthwhile to push back against it, separately from acknowledging the useful
information in this article. (And the grandparent comment you replied to also
did some of this as well, of course!)

~~~
gary_bernhardt
I agree with you in general. In this case there's only one coherent taxonomy
in widespread use so I think it's reasonable to say "just use it".

It's unfortunate that people who aren't already experts on a topic can't tell
whether that kind of decree represents consensus or someone's idiosyncratic
opinion (and there's plenty of both in general).

Framing is a different thing, though, and I can't comment there since I
haven't re-read the whole article recently.

------
cessor
I often found that these terms are not very usefull when explaining the
concepts of IoC in testing (which is essentially what they do) to colleagues
who were unfamiliar with it. Programming in .NET I usually tried to use
frameworks that avoided the terms, such as NSubstitute where you create an
object by substitution:

var format = Substitute.For<IFormatCode>();

I haven't used it in a while but I remember that Rhino Mocks asked for
ridiculous code like

var format = MockRepository.GenerateStub<IFormatCode>();

(Which one is it, a Mock or a Stub? And: Does it matter?)

I recommend Gerard Meszaros excellent book XUnit Test Patterns, he makes more
fine grained distinctions between different aspects of testing. I liked his
notion that you simply create objects that produce or react to "indirect input
and output" (i.e. exceptions, opcodes, sideeffects) rather than "direct input
and output" (which is what "arrange" and "assert" are checking). Mocks and
stubs are only realizations of different patterns.

[http://xunitpatterns.com/](http://xunitpatterns.com/)

~~~
freshhawk
That's an outstanding book. I'm not a Java programmer and that still might be
the best book on testing, how to design tests, what to test and how think
about testing at a high level that I've read.

------
taeric
Every validation you do on a mock is an assertion on outside behavior that is
in no way coupled with your test. If that behavior changes, your test is now
false. Not failing. False. That concerns me.

~~~
freshhawk
Yeah, maybe there is an approach that works well with mocks but this has
always concerned me as well. It's rare (for me anyway) that I want to test
which calls a function makes rather than if the function returns the correct
result.

I can imagine scenarios where that is useful and I know how to use mocks when
that comes up ... but the examples are always a system where mock based
testing is strangely coupled to implementation, very fragile and have the
scary failure mode you describe.

~~~
lojack
Typically, I find that I'm concerned with what calls a function makes when
those calls interface things external to my program. I.e. I'm asserting that a
request to a given http endpoint is made, or that an smtp client sends an
email. I assume the external libraries work and am testing my interface to
them.

~~~
taeric
This is where I find myself having to use these. Though, I greatly prefer to
have the test merely check for the result of the call, if I can. e.g., if I
have to post to a url to delete something, check to see if said something
exists. In the end, it is not the call that I care about, but what the call
was supposed to do.

This way can lead to brittle tests, clearly. But the reality seems to be that
brittle systems lead to brittle tests. There is no testing panacea.

------
ternaryoperator
This article is almost universally cited when a book or article on testing or
TDD begins the inevitable discussion of mocks/fakes/stubs. But in real life,
this is a distinction without difference. I have never once heard someone use
the term 'mock' and be misunderstood because he/she should've used 'stub'.

------
backslash_16
How do you test your code that interacts with external components, like
sending emails to a mail server or making an external API call without using
some sort of test fake or stub? (using the definition of them from the
article)

I'm new to TDD and refactoring legacy code for testability. With the code
architecture I have it looks and feels like I need either a mock, fake, or
stub.

I'm using an IExternalComponent interface as a parameter and for the concrete
implementation I can either pass the real thing (it's non deterministic, this
works if the service is up) or I can pass a test double that allows me to
throw exceptions at will and force failure conditions to be tested.

Is there another way of doing this that I am missing?

------
born_of_dust
Love this article.

