TestRestTemplate can be used as an efficient alternative to RestTemplate in
the spring boot integration tests.
It has all methods to send requests to the server and it has methods to enable
basic authentication when sending requests to the server.
Maven dependencies
We need spring-boot-starter-test dependency which contains TestRestTemplate
and provides support for our Rest API testing.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Rest API endpoints
An overview of our API endpoints for which we are about to write a test.
- All endpoints have content-type as application/JSON.
- All endpoints have x-requestid as header parameters which act as unique identifiers for requests.
- There are two GET endpoints one to get all employees and another to get details by employee id.
- The POST and PUT endpoints take a request body for creating and updating details.
Spring boot TestRestTemplate example
Let's see how we can use TestRestTemplate to test our spring boot controllers
which we have already created in the previous Rest API using Spring boot Framework.
Spring boot TestRestTemplate autowired
The TestRestTemplate will only be auto-configured when
@SpringBootTest is configured with a webEnvironment, which means
it will start the web container and listen for HTTP requests.
It is not necessary to provide the full URL along with the host instead a URL
is sufficient.
Spring boot TestRestTemplate GET example
In the header, we have added application/JSON as the content type.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Swagger2SpringBoot.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class EmployeeControllerTest {
@Autowired
TestRestTemplate testRestTemplate;
@Autowired
ObjectMapper mapper;
@Test
public void testGetEmployeeEndpoint() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("x-requestid", "12344");
HttpEntity<Employee> request = new HttpEntity<>(headers);
ResponseEntity<Employees> response = testRestTemplate.exchange("/employee/employee", HttpMethod.GET, request,
Employees.class);
assertEquals(200, response.getStatusCodeValue());
}
}
Spring boot TestRestTemplate with headers and query parameters
In the below test, we are calling the get employee by ID endpoint
where employeeid is a path parameter.
We can directly inject the path parameter in the URL by hardcoding it. If the
endpoint requires more than one path or query parameter, it is best to create
a dynamic URL and send the parameters in a map.
@Test
public void testGetEmployeeBasedOnId() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("x-requestid", "12344");
HttpEntity<Employee> request = new HttpEntity<>(headers);
Map<String, String> queryAndPAthParameters = new HashMap<>();
queryAndPAthParameters.put("employeeid", "1");
ResponseEntity<Employee> response = testRestTemplate.exchange("/employee/employee/{employeeid}", HttpMethod.GET,
request, Employee.class, queryAndPAthParameters);
assertEquals(200, response.getStatusCodeValue());
assertSame(1, response.getBody().getId());
}
Spring boot TestRestTemplate post example
In the below test, we are calling the add employee POST endpoint which takes a
request body. Until now we have seen how to send header and path, query
parameters.
@Test
public void testAddEmployee() throws JsonMappingException, JsonProcessingException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("x-requestid", "12344");
// request body
String requestBody = "{\"id\":1,\"name\":\"CodeBooker\",\"jobTitle\":\"Developer\",\"mobileNo\":\"9840353535\",\"joinedDate\":\"20-05-2019\",\"gender\":\"male\",\"salary\":25000,\"department\":{\"id\":\"1\",\"name\":\"Application Developement\"},\"project\":{\"id\":\"1\",\"name\":\"xxx-Project\"}}";
//convert json to pojo
Employee employee = mapper.readValue(requestBody, Employee.class);
Map<String, String> queryAndPAthParameters = new HashMap<>();
queryAndPAthParameters.put("employeeid", "1");
// Adding request body to request entity
HttpEntity<Employee> request = new HttpEntity<>(employee, headers);
ResponseEntity<Void> response = testRestTemplate.postForEntity("/employee/employee/", request, null);
assertEquals(204, response.getStatusCodeValue());
}
We are using Jackson ObjectMapper to convert JSON string to Java POJO class.
Spring boot TestRestTemplate put example
The update employee PUT endpoint is used to update existing employee details.
The test below sends all parameters and the request body to the endpoint to
update the details.
@Test
public void testUpdateEmployee() throws JsonMappingException, JsonProcessingException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("x-requestid", "12344");
// request body
String requestBody = "{\"id\":1,\"name\":\"Coder\",\"jobTitle\":\"Developer\",\"mobileNo\":\"9840353535\",\"joinedDate\":\"20-05-2019\",\"gender\":\"male\",\"salary\":25000,\"department\":{\"id\":\"1\",\"name\":\"Application Developement\"},\"project\":{\"id\":\"1\",\"name\":\"xxx-Project\"}}";
Employee employee = mapper.readValue(requestBody, Employee.class);
// Adding request body
HttpEntity<Employee> request = new HttpEntity<>(employee, headers);
Map<String, String> queryAndPAthParameters = new HashMap<>();
queryAndPAthParameters.put("employeeid", "1");
ResponseEntity<Void> response = testRestTemplate.exchange("/employee/employee/{employeeid}", HttpMethod.PUT,
request, Void.class, queryAndPAthParameters);
assertEquals(204, response.getStatusCodeValue());
}
Run our integration test case and check the result.
Basic Authentication in TestRestTemplate
All endpoints are secured using basic authentication. The TestRestTemplate has
a method to pass basic authentication when accessing rest endpoints.
Passing username and password in the constructor when creating the
TestRestTemplate object.
TestRestTemplate testRestTemplate = new TestRestTemplate("username", "passoword");
We can also pass credentials using the withBasicAuth method in
TestRestTemplate when making HTTP call to the endpoint.
testRestTemplate.withBasicAuth("username", "passoword").exchange("/employee/employee/{employeeid}",
HttpMethod.PUT,request, Void.class, queryAndPAthParameters);
Passing username and password in HTTP header.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBasicAuth("username", "passoword");
headers.set("x-requestid", "12344");
Tags:
spring boot