Reputation: 937
I am trying to write a unit test for rest template that is making http calls. I have created the rest template with the rest template builder, shown below. the rest template is set to configure read and connection timeouts. I also have a retry template that is to execute retries when the application has a timeout. I am at the point where I have specified the http methods: postForEntity, exchange, and getForEntity that need to retried in the retry template and need help with writing unit tests. I started with the getForEntity method but am receiving a different output from what is expected. any assistance with this would be helpful.
Rest Template
@Bean
public RestTemplate restTemplate() {
return new RestTemplateBuilder()
.setConnectTimeout(Duration.ofSeconds(10))
.setReadTimeout(Duration.ofSeconds(10))
.build();
}
Retrying getForEntity
public ResponseEntity getForEntity(URI uri, Class c) {
return retryTemplate.execute(retryContext -> {
return restTemplate.getForEntity(uri, c);
});
}
Unit Test
public class RetryRestTemplateTest {
@Mock
private RestTemplate restTemplate;
@Mock
private RetryTemplate retryTemplate;
private RetryRestTemplate retryRestTemplate;
String testUrl = "http://localhost:8080";
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
retryRestTemplate = new RetryRestTemplate(
restTemplate,
retryTemplate
);
}
@Test
public void getForEntity() throws URISyntaxException{
URI testUri= new URI(testUrl);
ArgumentCaptor<URI> argument = ArgumentCaptor.forClass(URI.class);
doReturn(new ResponseEntity<>("ResponseString", HttpStatus.OK))
.when(restTemplate).getForEntity(any(URI.class), eq(String.class));
assertThat(restTemplate.getForEntity(testUri, String.class), is(HttpStatus.OK));
verify(restTemplate).getForEntity(argument.capture(), eq(String.class));
assertThat(argument.getValue().toString(), is(testUri));
}}
My expected should be is <200 OK> and my actual is <<200 OK OK,ResponseString,[]>>
Any help on this would be helpful as I am not that experienced with Mockito and Junit.
Upvotes: 0
Views: 2280
Reputation: 5309
Your expectations are not aligned with the code you wrote getForEntity
does not return a HttpStatus
instance, instead it returns a ResponseEntity<String>
. Comparing a ResponseEntity<String>
with a HttpStatus
will never yield equal.
A fixed version of your test:
@Test
public void getForEntity() throws URISyntaxException {
URI testUri = new URI(testUrl);
ArgumentCaptor<URI> argument = ArgumentCaptor.forClass(URI.class);
doReturn(new ResponseEntity<>("ResponseString", HttpStatus.OK))
.when(restTemplate).getForEntity(any(URI.class), eq(String.class));
assertThat(restTemplate.getForEntity(testUri, String.class).getStatusCode(),
CoreMatchers.is(HttpStatus.OK));
verify(restTemplate).getForEntity(argument.capture(), eq(String.class));
assertThat(argument.getValue(), CoreMatchers.is(testUri));
}
Some side note: The test does not really test getForEntity
, it tests that a java proxy you created with mockito does return the mocked result. Imho you are actually testing if the mock framework works...
doReturn(new ResponseEntity<>("ResponseString", HttpStatus.OK)).when(restTemplate).getForEntity(any(URI.class), eq(String.class));
As discussed in the comments, an integration test of the RestTemplate
could be:
package com.example.demo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import java.io.IOException;
import java.net.URI;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
public class RetryRestTemplateTest {
private final MockWebServer server = new MockWebServer();
@BeforeEach
public void setup() throws IOException {
server.start();
}
@AfterEach
public void teardown() throws IOException {
server.close();
}
@Test
public void getForEntity() {
URI testUri = server.url("/").uri();
server.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> forEntity = restTemplate.getForEntity(testUri, String.class);
assertThat(forEntity.getStatusCode(), is(HttpStatus.OK));
assertThat(forEntity.getBody(), is("{}"));
}
}
The following test dependencies are needed:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.2.2</version>
<scope>test</scope>
</dependency>
Upvotes: 1