Mockito's `reset` method is used to reset a mock object so that it can be reused later in tests. However, when using the `@Spy` annotation, the behavior is slightly different compared to regular mocks.
Understanding `@Spy`
The `@Spy` annotation in Mockito is used to create a spy object. A spy object is a real object that has been wrapped by Mockito, allowing you to stub certain methods while still calling the real methods for others. Every call to a spy object is delegated to the real object unless you explicitly stub it using `doReturn`, `doThrow`, etc.[2].
Resetting a Spy
When you use `reset` on a spy object, it resets the mock's behavior but does not reset the underlying real object. This means that any stubbing you've done on the spy will be lost, but the real object's state remains unchanged. This can be problematic if your test relies on the state of the real object being reset as well.
Example
Consider a scenario where you have a list that you want to spy on:
java
@Spy
List list = new LinkedList();
// Stubbing a method on the spy
doReturn("Mocked Value").when(list).get(0);
// Resetting the spy
reset(list);
// After reset, the stubbing is lost, but the list remains the same
After calling `reset(list)`, any stubbing you've done (like `doReturn("Mocked Value")`) will no longer work. However, the list itself remains unchanged; it still contains the same elements and has the same state as before the reset.
Best Practices
While it is technically possible to use `reset` with a spy, it is generally not recommended. The use of `reset` can indicate poor test design, as it often suggests that the test is overly complex or that the object under test is not properly isolated[5]. Instead of resetting, consider creating a new spy or mock for each test method to ensure a clean and predictable state.
If you need to reset invocations (i.e., verify how many times a method was called), you can use `Mockito.clearInvocations()` instead, which is more targeted and does not reset stubbing[5].
In summary, while you can use `reset` with `@Spy`, it's generally better to avoid it and instead focus on creating clean, isolated tests that don't require resetting mocks or spies.
Citations:[1] https://www.tutorialspoint.com/mockito/mockito_resetting_mock.htm
[2] https://www.vogella.com/tutorials/Mockito/article.html
[3] https://www.lambdatest.com/automation-testing-advisor/selenium/methods/org.mockito.Mockito.reset
[4] https://reflectoring.io/clean-unit-tests-with-mockito/
[5] https://softwareengineering.stackexchange.com/questions/188299/is-this-an-appropriate-use-of-mockitos-reset-method
[6] https://dzone.com/refcardz/mockito
[7] https://stackoverflow.com/questions/15090317/resetting-mockito-spy
[8] https://github.com/mockito/mockito/issues/529