TestRestTemplate can be used to send http request in our Spring Boot integration tests. Such tests are usually executed with Spring boot run as a local server in a random port @LocalServerPort. So just need to create the request in integration tests and send it like a clients of your servers. TestRestTemplate have all necessary methods to send the request to server with a convenient way similar to RestTemplate.
Let’s see a basic example. Here is a minimal controller:
@RestController
public class PingController {
@GetMapping("/hello")
public String echo() {
return "Hello";
}
}
Let’s write a test for the above endpoint using org.springframework.boot.test.web.client.TestRestTemplate:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class DemoTest {
@Autowired TestRestTemplate restTemplate;
@Test
public void testHello() {
ResponseEntity<String> respEntity = restTemplate.getForEntity("/hello", String.class);
assertThat(respEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(respEntity.getBody()).isEqualTo("Hello");
}
}
Since you need to test the REST endpoint, we are starting the embedded servlet container by specifying the webEnvironment attribute of @SpringBootTest.
The default webEnvironment value is WebEnvironment.MOCK, which doesn’t start an embedded servlet container.
The following webEnvironment values are available:
- MOCK (default) Loads a WebApplicationContext and provides a mock servlet environment. It will not start an embedded servlet container.
- RANDOM_PORT Loads a ServletWebServerApplicationContext and starts an embedded servlet container listening on a random available port.
- DEFINED_PORT Loads a ServletWebServerApplicationContext and starts an embedded servlet container listening on a defined port (server.port).
- NONE Loads an ApplicationContext using SpringApplication but does not provide a servlet environment.
Generally speaking, while running the integration tests that start the embedded servlet containers, it is better to use WebEnvironment.RANDOM_PORT so that it won’t conflict with other running applications, especially in Continuous Integration (CI) environments where multiple builds run in parallel.
Testing Secured Controller/Service Methods
Spring boot provides several ways to test these secured endpoints. Before that, add the following dependencies to enable Spring Security and security testing capabilities:
<?xml version="1.0" encoding="UTF-8"?><project>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</project>
When you add the Security starter without custom security configurations, Spring Boot endpoints will be secured using HTTP basic authentication with a default user and generated password. To override that, you can configure credentials in application.properties as follows:
security.user.name=admin security.user.password=password security.user.role=USER,ADMIN
Let’s modify the above TestRestTemplate to test REST endpoints, passing the HTTP basic auth parameters, as follows:
@RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) public class DemoTest {
@Autowired TestRestTemplate restTemplate;
@Test public void testHello() throws Exception {
ResponseEntity < String > respEntity = restTemplate.withBasicAuth("admin", "password").getForEntity("/hello", String.class);
assertThat(respEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(respEntity.getBody()).isEqualTo("Hello");
}
}
Note that you have passed the credentials using restTemplate.withBasicAuth(“admin”, “password”).
Also note that by using TestRestTemplate, you can invoke REST endpoints using relative paths like “/hello” instead of specifying the complete URL http://localhost:/ping
Found the article helpful? if so please follow us on Socials