mocking resttemplate exchange always returns null
Asked Answered
A

7

6

I'm trying to mock a restTemplate.exchange method through mockito but it always returns a null value no matter what i return through mock , even if i throw an exception:

this is the actual code :

ResponseEntity<List<LOV>> response = restTemplate.exchange(url, GET, null,new ParameterizedTypeReference<List<LOV>>() {});

mockito code:

 ResponseEntity<List<LOV>> mockResponse = new ResponseEntity<List<LOV>>(mockLovList() ,HttpStatus.ACCEPTED);

Mockito.when(restTemplate.exchange(any(), eq(GET), any(), ArgumentMatchers.<ParameterizedTypeReference<List<LOV>>>any())).thenReturn(mockResponse);

Every argument is of type ArgumentMatchers in the exchange mock , mockLovList() returns a list of LOV

it should return whatever i mocked , but it always returns null

Arissa answered 9/4, 2019 at 10:28 Comment(0)
G
3

Here's a working example of a RestTemplate.exchange() mock test:

import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;

import static org.mockito.Mockito.*;

public class MyTest {

    @Test
    public void testRestTemplateExchange() {
        RestTemplate restTemplate = mock(RestTemplate.class);

        HttpEntity<String> httpRequestEntity = new HttpEntity<>("someString");

        List<String> list = Arrays.asList("1", "2");
        ResponseEntity mockResponse = new ResponseEntity<>(list, HttpStatus.ACCEPTED);
        when(restTemplate.exchange(anyString(), any(), any(), any(ParameterizedTypeReference.class), any(Object[].class)))
                .thenReturn(mockResponse);


        final ResponseEntity<List<String>> exchange = restTemplate.exchange("/someUrl", HttpMethod.GET, httpRequestEntity, new ParameterizedTypeReference<List<String>>() {
        });

        Assert.assertEquals(list, exchange.getBody());

    }

}
Gymno answered 9/4, 2019 at 12:11 Comment(3)
i'm doing the same thing but doesn't work for me . i've commented in the other answer what error it gives while doing mockito.verifyArissa
it works when i have a 5th argument in real exchange call ..this argument any(Object[].class), but not if 5th argument is null in real exchange method , i'm not passing anything in the last argument in the real exchange call just 4 arguments , i'dont need itArissa
@Arissa I have the same issue but I couldn't fix it. How can I fix it? Here is the link : #76309382Demonize
J
2

You need to make sure that your mocks are initialised before you are setting or injecting in a service. Like this-

@Mock
RestTemplate restTemplate;
@Before
public void init() {
    MockitoAnnotations.initMocks(this);
    userData = new UserService(restTemplate);
}
Juniorjuniority answered 2/7, 2021 at 14:35 Comment(1)
this is actually the correct answerPriapism
T
1

What about:

when(restTemplate.exchange(anyString(), any(), any(),
   eq(new ParameterizedTypeReference<List<LOV>>() {})))
.thenReturn(responseEntity);

If you use:

when(restTemplate.exchange(anyString(), any(), any(),
   any(ParameterizedTypeReference.class)))
.thenReturn(responseEntity);

You come across Unchecked assignment. You don't need also the 5th argument.

Thermae answered 27/6, 2022 at 12:58 Comment(0)
F
0

First you can verify if the method call is correct using

 Mockito.verify(restTemplate).exchange(any(), eq(GET), any(), any(ParameterizedTypeReference.class)))

Mockito shows a very nice output including the actual method call.

Additionally, you may refer to Deep Stubbing or Testing anonymous classes

Fairtrade answered 9/4, 2019 at 11:46 Comment(3)
yeah , this itself is not working , its giving java.lang.reflect.InvocationTargetExceptionArissa
Wanted but not invoked: restTemplate.exchange( <any>, GET, <any>, <any org.springframework.core.ParameterizedTypeReference> );Arissa
However, there was exactly 1 interaction with this mock: restTemplate.exchange( "url", GET, null, ParameterizedTypeReference<java.util.List<c.LOV>>Arissa
A
0

I had the same problem (at least 2 involving this problem) and after searching for an plausible answer, I could fix it successful.

Before my explanation, I'll share 2 explanations that helped me. How do I mock a REST template exchange? and Mocking RestTemplate.exchange() method gives null value.

So, basically, the point is that every test case involving any RestTemplate's method has to give every argument correctly. If it is not ok, than Mockito fails and throws an exception like that:

org.mockito.exceptions.misusing.PotentialStubbingProblem

or with a NullPointerException getting ResponseEntity from restTemplate.exchange (it is your case)

Before (I'm hidding some implementations. Mockito threw an exception)

when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(), 
                    ArgumentMatchers.<ParameterizedTypeReference<FilterBean>>any())).thenReturn(responseEntityFilterBean);

Mockito exception

org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict stubbing argument mismatch. Please check:

  • this invocation of 'exchange' method: restTemplate.exchange( "/filter", GET, <[Content-Type:"application/json"]>, class br.com.test.bean.FilterBean ); -> at br.com.test.service.FilterService.getFilterStatus(FiltroService.java:60)
  • has following stubbing(s) with different arguments:
    1. restTemplate.exchange("", null, null, null);

It's indicating that arguments aren't ok!

Changing my code it fixed my problem.

                when(restTemplate.exchange(ArgumentMatchers.anyString(), 
                    ArgumentMatchers.any(HttpMethod.class),
                    ArgumentMatchers.any(), 
                    ArgumentMatchers.<Class<FilterBean>>any())).thenReturn(responseEntityFilterBean);

In your case, try to do this and It'll solve:

        when(restTemplate.exchange(ArgumentMatchers.anyString(), 
                    ArgumentMatchers.any(HttpMethod.class),
                    ArgumentMatchers.any(), ArgumentMatchers.<Class<List<String>>>any())))
            .thenReturn(mockResponse);
Azygous answered 14/10, 2021 at 20:49 Comment(0)
F
0

I ran into this error due to mismatched types, my url was a URI not a String. This is what worked for me.

when(restTemplate.exchange(
  ArgumentMatchers.any(URI.class),
  ArgumentMatchers.any(HttpMethod.class),
  ArgumentMatchers.any(),
  ArgumentMatchers.eq(String.class)
)).thenReturn(mockResponse);

Note my project used String.class not ParameterizedTypeReference

Forage answered 12/10, 2022 at 4:48 Comment(1)
I have the same issue but I couldn't fix it. How can I fix it? Here is the link : #76309382Demonize
G
0
public class EmployeeServiceTest {

   @Mock
   private RestTemplate restTemplate;

   // Instiantiating the service is important, otherwise resttempate null pointer error is thrown.
   @InjectMocks
   private EmployeeService empService = new EmployeeService();

  @Test
  public void givenMockingIsDoneByMockito_whenGetIsCalled_shouldReturnMockedObject() {
    Employee emp = new Employee(“E001”, "Eric Simmons");
    Mockito
      .when(restTemplate.getForEntity(
        “http://localhost:8080/employee/E001”, Employee.class))
      .thenReturn(new ResponseEntity(emp, HttpStatus.OK));

    Employee employee = empService.getEmployee(id);
    Assertions.assertEquals(emp, employee);
  }
}
Gonsalez answered 13/1, 2023 at 10:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.