Mocking vs Spying

According to the API docks - both can be used to mock methods or fields. The difference is that with a mock, you are creating a complete mock or fake object whilst with a spy, there is the real object and you just spying or stubbing out specific methods.

When using mock objects (e.g. @Mock), the default behaviour of the method when not stub is do nothing. Meaning, if it's a void method, then it will do nothing when you call the method or if its a method with a non void return type then it may return null, empty, or the default value. So it is important to set up the expectations of the methods that will be used during the test.

When working as a spy, then a whole object actually does exist, Because the object is real, the method is real if do not stub out the method, Mockito will then call the real method. If you want to Spy on or change the method, then you should stub it out.

Let me explain it another way

  1. Mocks are NOT stubs, fakes or dummys

  2. Mocks create a scaffold object that needs to be populated with the methods that are expected to be called during the test, this is known as setting up the expectations (usually done through the when() method on the mock)

  3. Spies create an object from a concrete object, wrapping the concrete object in scaffolding. This allows the methods on the concrete object to be overridden in the test during the setting up of the expectations.

  4. When writing tests be careful you don’t end up trying to test the mock and not the CUT