What is the difference between mock & stub?

Asked

Viewed 9,074 times

35

  • In what situations should be used?
  • What’s the difference between them?

2 answers

32


What’s the difference between mock and stub?

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:

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

As a mock would have the following responsibility:

  • The test must invoke method A first, passing value 1 as parameter, hence return B.
  • The test must after invoke method X, passing value 2 as parameter, hence return Y.
  • If the test doesn’t follow exactly this sequence, it glitch.

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.

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

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 mockto test whether a code sluice in the expected way when it comes to interactions with the component that mock is replacing.

Another stuntman in history:

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.

Concluding:

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.

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

Dummy

These are objects used to fill a list of parameters when what they contain is not relevant. These objects will not actually be used.

Fake

They are objects with real implementations but not doing exactly what is expected in production environment.

Stubs

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.

Mocks

Are objects with implementations specifying how a method is expected to be used in real code. It is with them that you replaces behaviors.

Completion

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.

  • 2

    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)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.