Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock generic method in Java with Mockito?

How can we mock the IRouteHandlerRegistry? The error is Cannot 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);
}
like image 522
Jon Erickson Avatar asked Jul 24 '15 23:07

Jon Erickson


People also ask

What are Mockito methods in Java?

The brief description of the Mockito methods are given below: It is used to create mock objects of a given class or interface. Mockito contains five mock () methods with different arguments. When we didn't assign anything to mocks, they will return default values. All five methods perform the same function of mocking the objects.

What is the use of use of mocks in Java?

mock () method with Class: It is used to create mock objects of a concrete class or an interface. It takes a class or an interface name as a parameter. mock () method with Answer: It is used to create mock objects of a class or interface with a specific procedure. It is an advanced mock method, which can be used when working with legacy systems.

How to mock invocations to static method calls in Mockito?

As previously mentioned, since Mockito 3.4.0, we can use the Mockito.mockStatic (Class classToMock) method to mock invocations to static method calls. This method returns a MockedStatic object for our type, which is a scoped mock object.

Why when method from Mockito returns an object of type ongoingstubbing?

The whenmethod from Mockito returns an object of type OngoingStubbing<IHandleRoute<RouteDefinition>>. This is due to the compiler inferring the type parameter TRoutefrom the method <TRoute extends RouteDefinition> IHandleRoute<TRoute> getHandlerFor(TRoute route);


2 Answers

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);
like image 118
M A Avatar answered Oct 19 '22 07:10

M A


If you write like this it will be ok:

Mockito.doReturn(handler).when(registry).getHandlerFor(Mockito.any(route.class))
like image 23
Fariba Avatar answered Oct 19 '22 07:10

Fariba