35
- In what situations should be used?
- What’s the difference between them?
35
32
As a stub
only provides ready answers to the calls that will be made during the test, the mock
goes further and, in addition to providing the answers, also validates the calls - he knows the expected behavior of the system and tests this behavior.
Thus, when replacing a component during testing, a stub
would have the following responsibility:
As a mock
would have the following responsibility:
So we can put on the list of differences the fact that a mock
is more complex that a stub
.
It is common for developers to use mock frameworks (Jmock, Easymock, Mockito, ...) only as stubs (they do not validate the interaction between the tests and the "mocked" component). In this case the framework is specialized in mocks, but conceptually it is being used a stub and not a mock.
It is also not uncommon for developers to call all types of stuntmen "mock". And there’s nothing so wrong with that as long as you know in your heart the differences and complexity brought by each type.
Established that both serve to replace real components (they are "stuntmen" of these components) during the tests, and understood the difference between them, becomes clear when to use one and when to use another:
Use stub
to test whether a code, given a given input (stub methods ready responses), produces a certain output.
Use mock
to test whether a code sluice in the expected way when it comes to interactions with the component that mock is replacing.
Sometimes, in addition to providing ready-made answers, we want to know if the test actually invoked a method of the replaced component, or even how many times it invoked, but we don’t need to be so rigid as to check the sequence of calls or the value of the parameters, in this case we put some simple state in the stub
(method call counter, for example) and thus we get a spy
- another kind of stuntman standing between the stub
and the mock
, with some benefits of the second and almost all the simplicity of the first.
We use the different types of stuntmen as required by our tests, and we prefer the less complex types because they are less coupled to the production code, clearer to be understood, easier to maintain.
A list of stuntmen in ascending order of complexity would be:
first Dummy
2nd Fake
- Fake can be quite complex (such as an in-memory database or an embedded application server) but is not attached to your production code so it is considered to be of low complexity.
3º Stub
fourth Spy
5th Mock
The way to be able to use stunt doubles in a small amount or use the lower complexity doubles is to constantly pay attention to system design.
23
I think the canonical reference on the subject is article by Martin Fowler. It shows the difference between 4 types of substitutes:
These are objects used to fill a list of parameters when what they contain is not relevant. These objects will not actually be used.
They are objects with real implementations but not doing exactly what is expected in production environment.
They are objects created to facilitate the tests by giving predetermined answers and doing operations that provide additional information on the use of the test method. It is more important to give ease for the test to take place with ease than to perform the test, so much so that it has no function to make the test fail. Used to replace states.
Are objects with implementations specifying how a method is expected to be used in real code. It is with them that you replaces behaviors.
The choices depend somewhat on the style as you do your tests. I know a lot of people are not going to like this answer, but although I like the right things, I find it all too much for most projects. I’m not getting rid of the tools but it often looks like Nosql. It’s a lot to talk about but few really need it all. Just reinforce that thinking about your architecture and testing its implementation is critical.
Browser other questions tagged testing unit-testing mock
You are not signed in. Login or sign up in order to post.
Thank you for the answer, and I also agree with your conclusion! Sometimes we get too attached to these concepts and leave everything much more complex! (I believe that in some projects, this complexity is invariably necessary, but I also know that it is possible to have common sense and invest in architecture, making tests simpler)
– Rafael Fidelis