Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 7 years ago.
Although there are plenty of resources, even here on SO, only two of the terms are compared to each other in these Q/A.
So, in short, what is each one of them? And how they all relate to each other? Or don't they at all?
Difference between mock and stub is very simple - mock can make your test fail, while stub can't. That's all there is. Additionally, you can think of stub as of something that provides values. Nowadays, fake is just a generic term for both of them (more on that later).
Example
Let's consider a case where you have to build a service that sends packages via communication protocol (exact details are irrelevant). You simply supply service with package code and it does the rest. Given the snippet below, can you identify which dependency would be a stub and which mock in potential unit test?
public class DistributionService
{
public double SendPackage(string packageCode)
{
var contents = this.packageService.GetPackageContents(packageCode);
if (contents == null)
{
throw new InvalidOperationException(
"Attempt to send non-exisiting package");
}
var package = this.packageBuilder.Build(contents);
this.packageDistributor.Send(package);
}
}
It's fairly easy to tell that packageBuilder
simply provides value and there's no possible way it could make any test fail. That's a stub. Even though it might seem more blurry, packageService
is stub too. It provides a value (what we do with the value is irrelevant from stub's point of view). Of course, later we'll use that value to test whether exception is thrown, but it's still all within our control (as in, we tell stub exactly what to do and forget about it - it should have no further influence on test).
It gets different with packageDistributor
. Even if it provides any value, it's not consumed. Yet the call to Send
seems to be pretty important part of our implementation and we'll most likely want to verify it is called.
At this point we should get to a conclusion that packageDistributor
is a mock. We'll have a dedicated unit test asserting that Send
method was called and if for some reasons it wasn't - we want to know that, as it's important part of the entire process. Other dependencies are stubs as all they do is provide values to other, perhaps more relevant pieces of code.
Quick glance at TDD
Stub being stub, could be just as well replaced with constant value in naive implementation:
var contents = "Important package";
var package = "<package>Important package</package>";
this.packageDistributor.Send(package);
This is essentially what mocking frameworks do with stubs - instruct them to return configurable/explicit value. Old-school, hand-rolled stubs often do just that - return constant value.
Obviously, such code doesn't make much sense, but anyone who ever done TDD surely seen bunch of such naive implementations at the early stage of class development. Iterative development that results from TDD will often help identify roles of your class' dependencies.
Stubs, mocks and fakes nowadays
At the beginning of this post I mentioned that fake is just a generic term. Given that mock can also serve as stub (especially when modern mocking frameworks are concerned), to avoid confusion it's good idea to call such object a fake. Nowadays, you can see this trend growing - original mock - stub distinction is slowly becoming a thing of the past and more universal names are used. For example:
- FakeItEasy uses fake
- NSubstitute uses substitute
- Moq uses mock (name is old, but no visible distinction is made whether it's stub or mock)
References, further reading
- Mocks aren't stubs by Martin Fowler - you can see this article being linked virtually under any stub/mock question, and it's for a reason
- Exploring The Continuum Of Test Doubles by Mark Seemann - overview for all the confusing unit testing terminology (if you thought mock, fake and stub are enough, you probably should know there's also *dummy**, spy, double and what not)
- xunitpatterns.com - backing-website for huge unit-testing-patterns book, xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros
- Art of Unit Testing by Roy Osherove - excellent unit testing introductory book (the "mock can make test fail, stub not" are Roy's words, not mine)
Mock and Stub are both called Fake Object. In my opinion:
Stub is used to replace the external dependency, it make our tests run without exceptions. We must use Assert to determine the test fail or not. Stub is only suitable for testing the result of some functions are correct or not
Mock is more complex, often used to test behaviors, e.g. verifying is a function called or not
They are generally interchangeable but there are slight differences in my opinion.
- A mock/fake object will return realistic looking results.
- A stub will return a default fail/pass value.