Explain Codes LogoExplain Codes Logo

Mockito: Trying to spy on method is calling the original method

java
mockito
testing
stubbing
Alex KataevbyAlex Kataev·Dec 27, 2024
TLDR

Stop the real method execution in a Mockito spy by leveraging the doReturn() stubbing method directly. Refrain from using when().thenReturn() as it inadvertently activates the real method.

List<String> spyList = Mockito.spy(new ArrayList<>()); // Putting real get(0) method to bed Mockito.doReturn("Mocked!").when(spyList).get(0);

First use doReturn(), then when(). This prevents activation of the original code.

Mockito essentials: Stubbing techniques and beyond

Begin by learning proper stubbing techniques. For methods returning void, use doNothing().when(...):

// Lazy method, does nothing. Perfect candidate for a day off Mockito.doNothing().when(myClassSpy).methodWithNoReturn();

Avoid actual calls to original methods due to matchers like any(). Instead, opt for defined specific values, when feasible:

// Spy precision: ascending from vague ANY to clear Exact (0-index) Mockito.doReturn("Fixed response").when(spyList).get(Mockito.eq(0));

Ensure the method visibility is either public or protected. Spying on package-protected methods could kick you out of the pack - it tends to be a bit of a pickle across packages.

Matching versions: How Mockito version can make/break your stubbing

With Mockito's version 2.0+, be prepared for an upgrade in behavior, especially with the nullable() matcher. To enjoy this consistent behavior, keep your version squeaky clean:

// Not an addict for the Null? Say hello to Nullable() matcher! Mockito.doReturn("Mock result").when(myClassSpy).methodWithNullableArguments(Mockito.nullable(String.class));

Never underestimate the wealth of knowledge in the official documentation! It's like your coding bible, always dependable for the proper implementation of Mockito.

Making spies work for you: A deep dive into Mockito spy mechanics

Spying beans in the wild with @SpyBean

In the land of Spring, @SpyBean is the magic charm for effortlessly integrating spies with Spring beans. This ensures you're not left in the cold with proxying:

// Spy is now a Bean, Spring-ified and ready for action @Autowired @SpyBean private MyClass myClassSpy;

Remember to debug your tests to confirm that Mockito is the puppet master controlling your object.

Taming the beast: Handling exceptions with spies

In the sprawling realm of testing, using doThrow(), along with doReturn(), can create realistic scenarios:

// RuntimeException: Because every party needs a crasher! Mockito.doThrow(new RuntimeException()).doReturn("Mocked!").when(spyList).get(1);

The grand illusion: Matcher implications

The world of matchers offers wide possibilities and pitfalls. Some matchers might pull back the curtain revealing the true method calls. Be aware of method signatures:

// Sometimes, ANY int isn't good enough. Specify or face the music Mockito.doReturn("Mock value").when(myClassSpy).methodWithArgumentMatchers(Mockito.anyInt());

Face-off: Spying on real instances

For creating a real copy of the spy object, retain the original behavior:

// Making a REAL spy out of MyClass. James Bond approves MyClass realInstance = new MyClass(); MyClass spyInstance = Mockito.spy(realInstance);