How to mock generic method in Java with Mockito?
Solution 1
Even though TestRoute
is a subtype of RouteDefinition
, a IHandleRoute<TestRoute>
is not a subtype of IHandleRoute<RouteDefinition>
.
The when
method from Mockito returns an object of type OngoingStubbing<IHandleRoute<RouteDefinition>>
. This is due to the compiler inferring the type parameter TRoute
from the method
<TRoute extends RouteDefinition> IHandleRoute<TRoute> getHandlerFor(TRoute route);
to be RouteDefinition
since the argument passed to getHandlerFor
is declared of type RouteDefinition
.
On the other hand, the thenReturn
method is given an argument of type IHandleRoute<TestRoute>
whereas it expects an IHandleRoute<RouteDefinition>
, that is the type argument of the OngoingStubbing
mentioned earlier. Hence the compiler error.
To solve this, the simplest way is probably to change the declaration type of route
to be TestRoute
:
TestRoute route = new TestRoute();
IRouteHandlerRegistry registry = mock(IRouteHandlerRegistry.class);
IHandleRoute<TestRoute> handler = mock(IHandleRoute.class);
when(registry.getHandlerFor(route)).thenReturn(handler);
Solution 2
If you write like this it will be ok:
Mockito.doReturn(handler).when(registry).getHandlerFor(Mockito.any(route.class))
Solution 3
Mockito.when
argument should be a method not a mock.
The correct statement is:
when(registry.getHandlerFor (route)).thenReturn(handler)
Jon Erickson
Software Engineer with experience developing and supporting systems across the entire stack with recent focus on back-end, scalable systems. Also, recently completed an MS in Computer Science from Georgia Tech.
Updated on July 25, 2022Comments
-
Jon Erickson almost 2 years
How can we mock the
IRouteHandlerRegistry
? The error isCannot resolve method thenReturn(IHandleRoute<TestRoute>)
public interface RouteDefinition { } public class TestRoute implements RouteDefinition { } public interface IHandleRoute<TRoute extends RouteDefinition> { Route getHandlerFor(TRoute route); } public interface IRouteHandlerRegistry { <TRoute extends RouteDefinition> IHandleRoute<TRoute> getHandlerFor(TRoute route); } @Test @SuppressWarnings("unchecked") public void test() { // in my test RouteDefinition route = new TestRoute(); // TestRoute implements RouteDefinition IRouteHandlerRegistry registry = mock(IRouteHandlerRegistry.class); IHandleRoute<TestRoute> handler = mock(IHandleRoute.class); // Error: Cannot resolve method 'thenReturn(IHandleRoute<TestRoute>)' when(registry.getHandlerFor(route)).thenReturn(handler); }
-
Jon Erickson almost 9 yearsYou are correct, sorry I made an edit using my phone and didn't edit it correctly... this wasn't my issue though.
-
Jon Erickson almost 9 yearsthank you, this helps me with my understanding of java generics as well