Mocks Aren't Stubs (2007)
martinfowler.com
martinfowler.com
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.
I think the problem is the choice of words. Maybe mocks should actually be called "spies" instead and stubs "fakes".
Personally, I tend to think of stubs as being super basic. A stub class for me returns default values or throws NotImplemented or something as simple as possible. It doesn't maintain meaningful state. Mocks for me are generally simplified implementations like an in-memory store that replaces a DB. Frameworks like Moq have muddied my definition though because they call things mocks when they only return canned data. Building a real mock (fake) with real state using Moq tends to be a pain.
It's almost as if the experts don't all agree with this terminology.
Edit: This was a bit too snarky, but truthfully, I don't see evidence in the field that these definitions are widely used. I see evidence that an very small crowd is using these terms and asserting their correctness. Meanwhile the rest of the industry thinks anything they use as a "double" in a test is a "mock".
Even the people writing widely-used mocking libraries aren't using this terminology consistently.
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.
Here is a GitHub wiki where I break them down a decent amount: https://github.com/testdouble/contributing-tests/wiki/Test-D...
I've also written a JavaScript library called testdouble.js that has pretty detailed docs on their background purpose: https://github.com/testdouble/testdouble.js/blob/master/docs...
For what it's worth, Gerard Meszaros coined the term "test double" in his fantastic book (which most of you have never heard of, much less read) called xUnit Patterns. This is relevant to Gary's point, because like most things that require expertise specific terms only become useful as you grow close to the work. Most people don't use test doubles to facilitate isolated test-driven development, so most people won't come across the terms (or their sources).
I can't claim to be an expert in much, but—for reasons that evade my understanding—I do claim to be one in test double science™. What I can say is it can be tiresome when an expert has to constantly engage with relative novices who lack a curiosity with really engaging on the topic. Over the years, I've grown comfortable with the fact that most people—by which I mean, almost _all_ people—who want to talk about test doubles actually just want to fake something out in a test that's causing them pain. This is a perfectly fine thing to want to do, but it's orthogonal to why nuanced test double types & subtypes and jargon was ever necessary, which is mostly steeped in very rigorous schools of test-driven development.
There's no wrong way to do it. If you only write relatively "integrated" tests, nomenclature like "mock that out" won't cause you much harm but for the occasional eyeroll from people like me. But if you're interested in using tests as a sounding board to improve the design of your systems, they're one toolset for one style of approach (of many) that can help you in that endeavor—and which require the kind of specificity that Gary described above.
Not only does your own doc agree that in common usage, "mock" is a generic term for any test double, your docs also assert that a "partial mock" is "any actual object which has been wrapped or changed to provide artificial responses to some methods but not others". So by their "precise" definitions, a "partial mock" is actually not a partial "mock". Come on.
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!)
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.
I'm not saying that those should all be called mocks. I'm saying that are all called mocks by many developers already. There are frameworks that call themselves things like Moq and EasyMock that support multiple of the paradigms you describe. Picking "objects that demand to be interacted with" as the only real "mocks" feels arbitrary and frankly wrong given that the term "mock" has exactly nothing to do with requiring tests to cause certain method calls with certain params.
I'm totally fine with saying that we should recognize the difference between types of doubles and give them different names. I'm not on board with saying that suddenly a "method" is a function with no side effects as if that's some standard definition.
> and "we should not use separate words at all", mostly favored by those who haven't used a lot of doubles.
This is not subtle. And asserting that every with experience agrees with you does not make it true. I have written enough tests to have a legitimate opinion on this. I have also written test code filled with "mocks" that predates this article.
It's fine if you want to use different words. But you either have words for the different types or not. And if you have separate words, you either use the five existing ones or try to push five new ones. I think it's significant that you objected to my claim about the popular taxonomy without suggesting five alternative terms with even a fraction of the adoption. (I've built an entire career partly on popularizing this stuff and I've never even encountered a competing set of terms!)
I also don't believe it's reasonable to assert that I have to provide new terminology in order to point out that this definition is fundamentally problematic and does not match the common usage. But if you want a word, call it a preset (because all the interactions are defined in advance) or a mine field (because if you step in the wrong place, it blows up your test, and because your grandkids will still be dealing with the mess).
I hope your next monthly comment isn't wasted on someone who overreacts to one tiny piece like I did.
Indeed, nomenclature gives us clarity of concept and that precision yields efficiency of thought and communication.
Are the names arbitrary? I certainly thought so when I started. How did mock objects became expectation testing instruments and stubs didn't? How exactly is a stubbed class not a fake? Or would we use the word fake only for something like an in memory database? Aren't all test doubles fakes? Except, if a spy just wraps the object class, but allows calls through, then is it a double at all, or would it just be a probe? So are partial mocks and proxies liars?
Regardless of whether the names are arbitrary, it's useful to have them. It sure beats "double type A" and "Type B double". "Perhaps you should use the Second Double Form, the Third Form isn't really necessary." Ugh.
Perhaps there isn't a competing name set because it's hard enough getting everyone to agree these are distinct concepts. Maybe that would be easier with better names. After all, if there's popular rejection of the distinctions until the underlying concepts are understood, then the names aren't leading us to water on their own merit.
It seems, also, the more I hear the generation before mine talk about doubles, the more I find they use them very sparingly. The Beck's and Fowler's seem laid back about the nomenclature in favor of shared processual understanding.
We have a vague notion of a thing, so we call it "X". Later, as we learn more, we realize that we can think of X as a category of things, and that one of those things, annoyingly, should probably be called "X". Now we have a problem. Some people will call the thing X and some people will continue to call the category X, because they read our blog posts from five years ago, because they were so popular, because we are so awesome.
This is a sign of a good thing, even though it causes confusion. Now we have to roam the countryside saying "I know we say 'X' to mean this general thing, but we also say 'X' to mean that more specific thing. I'm really sorry. It's my fault. I recommend that you say 'Y' to refer to the category, but be prepared to read 'X' on the web. It is what it is."
It is what it is.
Correction: googletest/googlemock (in c++) can create mocks of non virtual classes, they use scripts to generate the mock code. Still you need a special test build to link with the mocked classes, in java/.net you dont have this problem because of reflection.
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.
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.
Side effects can be things like making an http request or writing to a file, it can be changing some global variable, but it can also be something like calling a public method of another public object. Since that function/method could also be impure, the very act of calling it is actually, in a way, part of the contract of the function under test: it returns a value, and it creates a side effect in the form of calling another function.
The only real way to test for those side effects is to pass in a stub or mock and to check that the function was called correctly. That makes your tests brittle, but it's the only way to make sure it does what you think it does (even if you only call the function for an intermediate return value, the fact that changing the intermediate function could change the result of the function under test).
Those tests are brittle because functions with side effects are, in fact, brittle, and favoring pure functions (where the only thing that matter is the return value, and dependencies are composed or passed as arguments) makes both your tests and your code better.
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.
then you have technical debt to repay, by making those pre-conditions satisfiable
Mocks lead you down a path where developers will eventually feel too scared or fatigued to refactor anything substantial.
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?