2
votes

I was just reading Martin Fowler's post Mocks Aren't Stubs. He defines the different test doubles (or rather references Gerard Meszaros's xUnit patterns book):

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
  • Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
  • Mocks are ... objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Part one of my question would be, is this even authoritative? Is this language widely used and understood?

The second part of my question is that it seems that my mocking framework of choice, Mockito, makes it easy to blur the line, certainly between mocks and stubs.

  • Everything is called "mock". Either by calling the Mockito.mock() method or with a @Mock annotation, you use the word "mock" to create mocks, stubs, and sometimes dummies (if a simple "new" won't do). The exception is a "spy" which might be used to make something like a "fake", but can also be used to wrap your system under test.
  • Even if you didn't care about the name of the method to create a test double, the double can be verified (or not) and you can include a capture in the verification step, which seem to include some things that a stub would do (remembering calls that were made) and mocks (verifying that certain expected calls were made).

The reason I ask is that I try to name my doubles according to the four things I see above, but then get confused sometimes whether something really has the role of stub or a mock. So, is this a deficiency of Mockito, or is this just how things have evolved and the distinction is not really important?

3
The difference is significant if you use it to your advantage. When I see a mock, I know that the dependency is the focus of the test. I look at it closely. When I see a stub, I know that I can safely ignore it.. it is just something that needs to be slotted in for the test to work - an incidental detail. I'd be surprised to see any asserts/expectations made on a stub. You can aid readability of your tests by correctly specifying a dependency as a stub or a mock.Gishu

3 Answers

6
votes

Actually, it's a strength of Mockito. A Mockito mock is an object on which you can either "stub" the methods, or "verify" the methods, or both. (Doing both for the same method is kind of a code smell, but that's another topic). So a Mockito mock is both a "stub" (in the Martin Fowler sense) and a "mock" (in the Martin Fowler sense); but you don't have to use it as both. Usually, a Mockito mock will act as EITHER a "stub", OR as a "mock"; less often as both.

In some other mocking frameworks, you don't have quite this level of flexibility. If you want to do "verifying" on a mock, you also have to do "stubbing". In these frameworks, the mocks MUST act as both a "stub" and as a "mock". As far as I understand, one of the factors that motivated Szczepan Faber to create Mockito was a desire to be able to separate "stub" behaviour, and "mock" behaviour (in the strict Martin Fowler senses of both words).

3
votes

The English word "mock" means "an imitation of lesser quality than the original". This is why even hand-rolled mocks (written without the aid of a framework like Mockito) are sometimes called mocks.

The language which Martin used is now a little bit out of date. He wrote it in the context of old mocking frameworks like JMock, before the "nice mocks" came along. In that era, mocks used to be strict; any interactions which hadn't been set up and weren't expected would fail.

Nowadays we tend to think of it a different way. If I'm a class, I have some other classes that I need to help me. They're either providing information, or doing some work for me - for instance, a repository might provide a list of employees, or save a new employee.

Mocks stand in for these collaborators, and we don't tend to use expectations on mocks any more. Instead, we set up mocks to provide information, then verify that they were asked to do any jobs that need to be done. Mockito was the first framework to work this way, and that's why the distinction is blurred - because whatever you're doing, you're mocking out a collaborator, and you no longer need to set up expectations. Moq works the same way in .NET.

Mockito's mocks by default don't even care if you use them and don't check (although you'll need to set up any information that they have to provide before-hand - the equivalent of a "stub").

Additionally, because Mockito provides "nice" mocks, you don't need to worry about setting expectations in case a dummy object is used somewhere - you can just use Mockito to create those, as well. And, just in case you want to add some simple behavior, Mockito lets you do callbacks easily on the arguments which are passed to it, so you can create "Fakes".

It doesn't really matter what they are - you're just mocking out a collaborating class, and the flexibility means that you don't need to worry about how you do that.

Early frameworks didn't provide this flexibility, hence Martin's differentiation, intended to help you use mocks appropriately. Hope this helps clarify things and explain why Mockito's flexibility isn't a deficiency, but - as David Wallace pointed out - a strength.

3
votes

According to what I understand from Gerard Meszaros' X-Unit test patterns, a mock is a test-double that includes the functionality of a dummy, a stub and a spy. You can check out the actual comparison he draws about them in pg.742 of that book.

Also this article might throw some light on your question. This article clearly states that

"A mock is dynamically created by a mock library (the others are typically produced by a test developer using code). The test developer never sees the actual code implementing the interface or base class, but can configure the mock to provide return values, expect particular members to be invoked, and so on. Depending on its configuration, a mock can behave like a dummy, a stub, or a spy."

enter image description here

Both the quote and the image were taken from this article. IMHO, a mock is intended to blur the line between a dummy, a stub and a spy.