- In which situations should be used?
- What's the difference between them?
stub
only provides ready-made answers to the calls that will be made during the test, mock
goes further and, in addition to providing the answers, also validates the calls - it knows the expected behavior of the system and test this behavior.
Thus, when replacing a component during testing, a stub
would have the following responsibility:
While a mock
would have the following responsibility:
So we can put in the list of differences the fact that a mock
is more complex than a stub
.
It is common for developers to use mocks frameworks (JMock, EasyMock, Mockito, ...) only as stubs (they do not validate the interaction between the tests and the "mockado" component). In this case the framework is specialized in mocks, but conceptually a stub is being used and not a mock.
It's also not uncommon for developers to call all types of stunts mock. And there's nothing so wrong about it as long as you hear the differences and the complexity brought by each type.
Given that both are meant to replace real components (they are "stunts" of these components) during testing, and the difference between them is understood, it is clear when to use one and when to use another:
Use stub
to test whether a code, given a given input (stub-ready methods), produces a certain output.
Use mock
to test if a code is expected in terms of interactions with the component that mock is replacing.
stub
(method call counter, for example) and thus get a spy
- another type of stunt that is between stub
and mock
, with some benefits of the second and almost all of the simplicity of the first.
We use the different stunt types as required by our tests, and we prefer less complex types because they are less coupled to the production code, clearer to understand, easier to maintain.
A list of stunts in ascending order of complexity would be:
1st Dummy
3rd Fake
4th Stub
5th Spy
The way to be able to use stunts in a small amount or to use the ones with the lowest complexity is the constant attention to system design.
I think the canonical reference on the subject is the Martin Fowler article . It shows the difference between 4 types of substitutes:
Objects are used to populate a parameter list when what is contained in them is not relevant. These objects will not be actually used.
They are objects with real implementations but do not do exactly what you expect in the production environment.
These are objects created to facilitate testing by giving pre-determined responses and by performing operations that provide additional information about using the method under test. It is more important to give facilities for the test to happen with ease than to run the test, so much so that it does not have the function of having the test fail. Used for replace states .
They are objects with implementations specifying how a method is expected to be used in real code. It is with them that you replace behaviors .
The choices depend a little on the style as you do your tests. I know a lot of people will not like this answer but even though I like the right things, I find all of this very exaggerated for most projects. I'm not undoing the tools but this often looks like NoSQL. It gives a lot to talk about but few really need it all. Just reinforcing that thinking well about your architecture and testing your implementation is critical.