How do I mock a REST template exchange?
155,244
Solution 1
You don't need MockRestServiceServer
object. The annotation is @InjectMocks
not @Inject
. Below is an example code that should work
@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
@Mock
private RestTemplate restTemplate;
@InjectMocks
private SomeService underTest;
@Test
public void testGetObjectAList() {
ObjectA myobjectA = new ObjectA();
//define the entity you want the exchange to return
ResponseEntity<List<ObjectA>> myEntity = new ResponseEntity<List<ObjectA>>(HttpStatus.ACCEPTED);
Mockito.when(restTemplate.exchange(
Matchers.eq("/objects/get-objectA"),
Matchers.eq(HttpMethod.POST),
Matchers.<HttpEntity<List<ObjectA>>>any(),
Matchers.<ParameterizedTypeReference<List<ObjectA>>>any())
).thenReturn(myEntity);
List<ObjectA> res = underTest.getListofObjectsA();
Assert.assertEquals(myobjectA, res.get(0));
}
Solution 2
This is an example with the non deprecated ArgumentMatchers class
when(restTemplate.exchange(
ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<String>>any()))
.thenReturn(responseEntity);
Solution 3
ResponseEntity<String> responseEntity = new ResponseEntity<String>("sampleBodyString", HttpStatus.ACCEPTED);
when(restTemplate.exchange(
Matchers.anyString(),
Matchers.any(HttpMethod.class),
Matchers.<HttpEntity<?>> any(),
Matchers.<Class<String>> any()
)
).thenReturn(responseEntity);
Solution 4
For me, I had to use Matchers.any(URI.class)
Mockito.when(restTemplate.exchange(Matchers.any(URI.class), Matchers.any(HttpMethod.class), Matchers.<HttpEntity<?>> any(), Matchers.<Class<Object>> any())).thenReturn(myEntity);
Solution 5
This work on my side.
ResourceBean resourceBean = initResourceBean();
ResponseEntity<ResourceBean> responseEntity
= new ResponseEntity<ResourceBean>(resourceBean, HttpStatus.ACCEPTED);
when(restTemplate.exchange(
Matchers.anyObject(),
Matchers.any(HttpMethod.class),
Matchers.<HttpEntity> any(),
Matchers.<Class<ResourceBean>> any())
).thenReturn(responseEntity);
Related videos on Youtube
Comments
-
Akka Jaworek almost 2 years
I have a service in which I need to ask an outside server via rest for some information:
public class SomeService { public List<ObjectA> getListofObjectsA() { List<ObjectA> objectAList = new ArrayList<ObjectA>(); ParameterizedTypeReference<List<ObjectA>> typeRef = new ParameterizedTypeReference<List<ObjectA>>() {}; ResponseEntity<List<ObjectA>> responseEntity = restTemplate.exchange("/objects/get-objectA", HttpMethod.POST, new HttpEntity<>(ObjectAList), typeRef); return responseEntity.getBody(); } }
How can I write a JUnit test for
getListofObjectsA()
?I have tried with the below:
@RunWith(MockitoJUnitRunner.class) public class SomeServiceTest { private MockRestServiceServer mockServer; @Mock private RestTemplate restTemplate; @Inject private SomeService underTest; @Before public void setup() { mockServer = MockRestServiceServer.createServer(restTemplate); underTest = new SomeService(restTemplate); mockServer.expect(requestTo("/objects/get-objectA")).andExpect(method(HttpMethod.POST)) .andRespond(withSuccess("{json list response}", MediaType.APPLICATION_JSON)); } @Test public void testGetObjectAList() { List<ObjectA> res = underTest.getListofObjectsA(); Assert.assertEquals(myobjectA, res.get(0)); }
However the above code does not work, it shows that
responseEntitty
isnull
. How can I correct my test to properly mockrestTemplate.exchange
?-
Akka Jaworek over 7 yearsanyone has an idea?
-
-
Martin Schröder almost 6 yearsDoesn't work with
org.hamcrest.Matchers
andorg.mockito.Matchers
is deprecated in favor of hamcrest. -
bpedroso almost 6 yearsYou can use it with generic matcher too. ArgumentMatchers.<Class<?>>any())
-
Roeland Van Heddegem over 5 years"Matchers" is deprecated and should be replaced with "ArgumentMatchers" because of a name clash. Class Matchers
-
Angelina almost 5 yearsHow do we add contents to the myEntity.getBody()? Mine comes back null
-
Sham Fiorin almost 5 yearsMatchers are deprecated, you should use Mockito
-
Mindaugas almost 5 years@Angelina since it's a real object just use an appropriate constructor i.e
ResponseEntity(T body, HttpStatus status)
-
Marino over 4 years@Mindaugas I´ve used the constructor but my response still is null ResponseEntity<String> response = new ResponseEntity<>( "a string",HttpStatus.OK );
-
Mindaugas over 4 years@Marino make sure that your mocked method that is supposed to return the response entity is being called and that it is infact configured to return said entity
-
Marino over 4 yearsI´m sorry, @Mindaugas but still doesn´t works! My test code is ResponseEntity<String> responseEntity = new ResponseEntity<>("sampleBodyString", HttpStatus.CREATED); doReturn(responseEntity).when(restTemplate).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), eq(String.class)); TokenBean tokenBeanResult = tokenService.refresh("refresh-token"); and my real code is: ResponseEntity<String> response = restTemplate.exchange(tokenApiConfig.getUrl(), HttpMethod.POST, request, String.class); and response is still null
-
Mindaugas over 4 years@Marino is request parameter of type HttpEntity.class? cause that is what you are using to mock the rest template call
-
G_V almost 4 yearsThe Matchers class is deprecated now
-
Lanon over 3 years
@Mock
and@InjectMocks
were a key in my test case. -
Skillz about 3 yearsI'm using a regular rest template and this was the only thing that worked
-
electrobabe over 2 yearsin my case:
when(restTemplate.exchange(any(String.class), eq(HttpMethod.GET), any(), eq(new ParameterizedTypeReference<String>() {}))).thenReturn(myEntity);