Reputation: 195
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
Upvotes: 6
Views: 22571
Reputation: 111
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);
}
}
Upvotes: 0
Reputation: 1
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
Upvotes: 0
Reputation: 1475
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.
Upvotes: 1
Reputation: 200
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:
- 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);
Upvotes: 0
Reputation: 31
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);
}
Upvotes: 3
Reputation: 24452
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());
}
}
Upvotes: 3
Reputation: 96
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
Upvotes: 0