Mocks are test doubles that register all the received calls but do nothing more than that. They do not return any value and they do not change state in any way. They are useful when we have a third-party framework that is supposed to call our code. By using mocks, we can observe all the calls and are thus able to verify that the framework behaves as expected.
Stubs are a bit more complicated when it comes to their implementation. They return values, but those values are predefined. It may seem surprising that the StubRandom.randomInteger() method always returns the same value (for example, 3), but it may be a sufficient stub implementation when we are testing the type of the returned value or the fact that it does return a value at all. The exact value may not be that important.
Finally, fakes are objects that have a working implementation and behave mostly like the actual production implementation. The main difference is that fakes may take various...