What is the difference between mock & stub?

28
  • In which situations should be used?
  • What's the difference between them?
asked by Laerte 13.10.2014 в 19:56
source

2 answers

23

What is the difference between mock and stub?

While a 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:

  • If the test invokes method A, return B.
  • If test invoke method X, return Y.

While a mock would have the following responsibility:

  • The test should invoke method A first, passing the value 1 as parameter, hence return B.
  • The test should then invoke the X method, passing the value 2 as a parameter, hence Y.
  • If the test does not exactly follow this sequence, it fails .

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.

In which situations using one is more advantageous than using the other?

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.

Another stunt in the story:

Sometimes, in addition to providing ready-made answers, we want to know whether the test actually invoked a method of the overridden component, or even how many times it invoked, but we do not 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 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.

Concluding:

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

  • Fake can be very complex (like an in-memory database or an embedded application server) but it is not coupled to your production code so it is considered to be of low complexity. .

  • 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.

    
answered by 15.10.2014 / 01:20
source
17

I think the canonical reference on the subject is the Martin Fowler article . It shows the difference between 4 types of substitutes:

Dummy

Objects are used to populate a parameter list when what is contained in them is not relevant. These objects will not be actually used.

Fake

They are objects with real implementations but do not do exactly what you expect in the production environment.

Stubs

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 .

Mocks

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 .

Conclusion

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.

    
answered by 13.10.2014 в 20:40