Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Can you explain the difference between using mocks and spies in Mockito


Can you explain the difference between using mocks and spies in Mockito


In Mockito, mocks and spies are both types of test doubles used for unit testing, but they serve different purposes and have distinct characteristics.

Mocks

**Mocks are completely fake objects created from the class of a type. They are used to replace dependencies in unit tests, allowing you to define their behavior entirely. Mocks do not execute the real methods of the underlying object; instead, they provide default behavior or behavior defined using Mockito stubbing methods, such as `when(...).thenReturn(...)`.

The primary use of mocks is to isolate the code under test from its dependencies. This is particularly useful when testing code that relies on external resources like databases or web services. By using mocks, you can test the code without needing these external resources, making your tests faster and more reliable.

Here's an example of creating a mock object:

java
List mockedList = mock(List.class);
when(mockedList.size()).thenReturn(10);
verify(mockedList).size();

Spies

**Spies, on the other hand, are partial mocks that wrap around real objects. They allow you to call all the normal methods of the object while still tracking interactions with it. Unless explicitly stubbed, spies execute the real methods of the underlying object. This makes spies useful when you want to partially mock an object, retaining some of its real behavior while overriding or verifying specific methods.

Spies are particularly useful for testing complex or legacy code that is difficult to refactor. They enable you to test real objects in isolation while allowing the real objects to execute their original code.

Here's an example of creating a spy object:

java
List list = new ArrayList();
List spyList = spy(list);
spyList.add("element");
verify(spyList).add("element");

Key Differences

- Creation: Mocks are created from the class of a type using `mock()`, while spies are created from actual instances using `spy()`.
- Behavior: Mocks do not execute real methods, while spies execute real methods unless stubbed.
- Purpose: Mocks replace dependencies entirely, while spies partially mock objects, allowing some real behavior.
- Use Cases: Mocks are ideal for isolating dependencies, especially external resources. Spies are useful for partial mocking and testing real objects with some overridden behavior.

In summary, while both mocks and spies are essential in Mockito for unit testing, they cater to different testing needs based on how much of the real object's behavior you want to retain or override.

Citations:
[1] https://www.javahabit.com/2023/04/25/How-to-Choose-Between-Mocks-and-Spies/
[2] https://stackoverflow.com/questions/15052984/what-is-the-difference-between-mocking-and-spying-when-using-mockito
[3] https://www.hypertest.co/unit-testing/mockito-mocks
[4] https://springframework.guru/mockito-mock-vs-spy-in-spring-boot-tests/
[5] https://www.testim.io/blog/mockito-spy/
[6] https://www.softwaretestinghelp.com/mocks-spy-mockito/
[7] https://stackoverflow.com/questions/28295625/mockito-spy-vs-mock
[8] https://www.studytonight.com/java-examples/spy-in-mockito
[9] https://intellipaat.com/blog/tutorial/mockito-tutorial/mockito-mock-vs-spy/