Home > database >  Difference between Mockito.<Response>any().getClass() and Mockito.<Class<Response>>
Difference between Mockito.<Response>any().getClass() and Mockito.<Class<Response>>

Time:10-13

I am trying to understanding how the generics work in case of Mockito.

I am trying to mock the RestTemplate, however the following code does not compile and I don't know why:

var expectedResponse = createServiceResponse();

when(restTemplate.exchange(anyString(), any(HttpMethod.class),
        Mockito.<HttpEntity<Object>>any(),
        Mockito.<ServiceResponse>any().getClass(), anyMap()))
        .thenReturn(ResponseEntity.ok(expectedResponse));

The compiler keeps giving me the error message:

Cannot resolve method 'thenReturn(org.springframework.http.ResponseEntity<T>)

But when I switch Mockito.<ServiceResponse>any().getClass() with Mockito.<Class<ServiceResponse>>any() the compilation succeeds.

Why is this happening ?

What is the difference between Mockito.<ServiceResponse>any().getClass() and Mockito.<Class<ServiceResponse>>any() ?

They should be the same thing right ?

I mean the class of ServiceResponse should be Class<ServiceResponse>. Right ?

I don't have a good grasp of advanced generics so I can't understand what the compiler is doing.

Please do add some description in the answer so that I can understand why this is working the way it is suppose to.

CodePudding user response:

Only in these cases, where the compiler cannot garantuee the returned type of the method (here restTemplate.exchange) we can use the non-type-safe equivalent syntax:

Mockito.doReturn(ResponseEntity.ok(expectedResponse))
    .when(restTemplate)
    .exchange(anyString(), any(HttpMethod.class),
        Mockito.<HttpEntity<Object>>any(),
        Mockito.<ServiceResponse>any().getClass(), anyMap()));

CodePudding user response:

What is the difference between Mockito.<ServiceResponse>any().getClass() and Mockito.<Class<ServiceResponse>>any()?

Mockito.<ServiceResponse>any() is an instance of ServiceResponse. And calling getClass() from any instance return Class<?>. getClass() is created to get the actual class of the instance, usually for runtime comparison.

On the other hand, Mockito.<Class<ServiceResponse>>any() is an instance of Class<ServiceResponse>

I mean the class of ServiceResponse should be Class. Right ?

Not really, consider following code

    private void dummy(ServiceResponse response) {
        System.out.println(response.getClass().equals(ServiceResponse.class));
    }

You can't guarantee the output is always true, as response can be of type CustomServiceResponse(extending ServiceResponse)

For your problem, just use ServiceResponse.class, simple and clear.

Further reading:
What is the difference between a.getClass() and A.class in Java? Why does a wildcard on a generic parameter require an explicit cast?
Java: getClass() of bounded type

  • Related