Explore Spring TestRestTemplate for Integration Testing

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.

Spring Boot RestTemplate vs TestRestTemplate for testing

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");

Post a Comment

Previous Post Next Post

Recent Posts

Facebook