Starter for testing Spring Boot applications with libraries including JUnit Jupiter, Hamcrest and Mockito
—
Pre-configured web testing tools including TestRestTemplate, MockMvc integration, WebTestClient support, and utilities for testing web applications and REST clients.
Key Imports:
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.web.client.RestClientException;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;Pre-configured RestTemplate for testing web applications with embedded servers.
/**
* Convenient alternative to RestTemplate for integration tests.
* TestRestTemplate is fault tolerant and does not extend RestTemplate to prevent injection problems.
* @since 1.4.0
*/
public class TestRestTemplate {
/**
* Create a new TestRestTemplate instance with a RestTemplateBuilder
* @since 1.4.1
*/
public TestRestTemplate(RestTemplateBuilder restTemplateBuilder);
/**
* Create a new TestRestTemplate with HttpClient options
*/
public TestRestTemplate(HttpClientOption... httpClientOptions);
/**
* Create a new TestRestTemplate with basic authentication
*/
public TestRestTemplate(String username, String password, HttpClientOption... httpClientOptions);
/**
* Create a new TestRestTemplate with builder, basic auth and HttpClient options
* @since 2.0.0
*/
public TestRestTemplate(RestTemplateBuilder builder, String username, String password, HttpClientOption... httpClientOptions);
/**
* Configure this TestRestTemplate with basic authentication
*/
public TestRestTemplate withBasicAuth(String username, String password);
/**
* Get the root URI for this TestRestTemplate
*/
public String getRootUri();
/**
* Retrieve representation by doing a GET on the specified URL
* @throws RestClientException if the request fails
*/
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
/**
* Retrieve representation by doing a GET on the specified URL
* @throws RestClientException if the request fails
*/
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
/**
* Retrieve representation by doing a GET on the specified URI
* @throws RestClientException if the request fails
*/
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
/**
* Create a new resource by POSTing the given object to the URI template
* @throws RestClientException if the request fails
*/
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables) throws RestClientException;
/**
* Create a new resource by POSTing the given object to the URI template
* @throws RestClientException if the request fails
*/
public <T> ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
/**
* Create a new resource by POSTing the given object to the URL
* @throws RestClientException if the request fails
*/
public <T> ResponseEntity<T> postForEntity(URI url, Object request, Class<T> responseType) throws RestClientException;
/**
* Execute the HTTP method to the given URI template
*/
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables);
/**
* Execute the HTTP method to the given URI template
*/
public <T> ResponseEntity<T> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String, ?> uriVariables);
/**
* Execute the HTTP method to the given URI
*/
public <T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType);
}
/**
* HttpClient configuration options for TestRestTemplate
*/
public enum HttpClientOption {
ENABLE_COOKIES,
ENABLE_REDIRECTS,
SSL
}Usage Examples:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class TestRestTemplateTest {
@Autowired
private TestRestTemplate restTemplate;
@LocalServerPort
private int port;
@Test
void getRequest() {
ResponseEntity<String> response = restTemplate.getForEntity(
"/api/hello", String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo("Hello World");
}
@Test
void postRequest() {
User user = new User("test@example.com", "Test User");
ResponseEntity<User> response = restTemplate.postForEntity(
"/api/users", user, User.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.CREATED);
assertThat(response.getBody().getEmail()).isEqualTo("test@example.com");
}
@Test
void withBasicAuth() {
TestRestTemplate authenticatedTemplate = restTemplate
.withBasicAuth("admin", "password");
ResponseEntity<String> response = authenticatedTemplate
.getForEntity("/api/admin/users", String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Test
void exchangeMethod() {
HttpHeaders headers = new HttpHeaders();
headers.set("X-Custom-Header", "custom-value");
HttpEntity<String> entity = new HttpEntity<>(headers);
ResponseEntity<String> response = restTemplate.exchange(
"/api/protected", HttpMethod.GET, entity, String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
}Auto-configuration for MockMvc in web layer tests.
/**
* Annotation for auto-configuring MockMvc
* @since 1.4.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ImportAutoConfiguration
public @interface AutoConfigureMockMvc {
/**
* Whether Spring Security's MockMvc integration should be applied
*/
boolean addFilters() default true;
/**
* The web application root directory
*/
String webAppRootDir() default "";
/**
* Whether MockMvc and WebDriver should be used
*/
boolean webDriverEnabled() default true;
/**
* How to print MockMvc result information
*/
MockMvcPrint print() default MockMvcPrint.NONE;
/**
* Whether to only print on failure
*/
boolean printOnlyOnFailure() default true;
}
/**
* MockMvc print options
*/
public enum MockMvcPrint {
/**
* Don't print
*/
NONE,
/**
* Print to System.out
*/
SYSTEM_OUT,
/**
* Print to System.err
*/
SYSTEM_ERR,
/**
* Print using SLF4J at DEBUG level
*/
LOG_DEBUG
}Usage Examples:
@WebMvcTest
@AutoConfigureMockMvc(print = MockMvcPrint.SYSTEM_OUT)
class MockMvcAutoConfigurationTest {
@Autowired
private MockMvc mockMvc;
@Test
void mockMvcIsConfigured() throws Exception {
mockMvc.perform(get("/api/test"))
.andExpect(status().isOk())
.andDo(print()); // Will print to System.out due to configuration
}
}Auto-configuration for WebTestClient in reactive web tests.
/**
* Annotation for auto-configuring WebTestClient
* @since 2.0.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ImportAutoConfiguration
public @interface AutoConfigureWebTestClient {
/**
* Timeout for WebTestClient operations
*/
String timeout() default "";
}
/**
* Customizer for WebTestClient.Builder
*/
@FunctionalInterface
public interface WebTestClientBuilderCustomizer {
/**
* Customize the WebTestClient.Builder
*/
void customize(WebTestClient.Builder builder);
}Usage Examples:
@WebFluxTest
@AutoConfigureWebTestClient(timeout = "10s")
class WebTestClientAutoConfigurationTest {
@Autowired
private WebTestClient webTestClient;
@Test
void webTestClientIsConfigured() {
webTestClient.get()
.uri("/api/reactive")
.exchange()
.expectStatus().isOk()
.expectBody(String.class)
.value(body -> assertThat(body).isEqualTo("Reactive Response"));
}
}
@TestConfiguration
static class WebTestClientConfig {
@Bean
public WebTestClientBuilderCustomizer customizer() {
return builder -> builder
.defaultHeader("X-Test-Header", "test-value")
.responseTimeout(Duration.ofSeconds(30));
}
}Utilities for handling URIs in local testing scenarios.
/**
* UriTemplateHandler for handling localhost URIs in tests
* @since 1.4.0
*/
public class LocalHostUriTemplateHandler implements UriTemplateHandler {
/**
* Create a new LocalHostUriTemplateHandler for the given Environment
*/
public LocalHostUriTemplateHandler(Environment environment);
/**
* Create a new LocalHostUriTemplateHandler for the given scheme
*/
public LocalHostUriTemplateHandler(Environment environment, String scheme);
/**
* Expand the given URI template with variables
*/
@Override
public URI expand(String uriTemplate, Map<String, ?> uriVariables);
/**
* Expand the given URI template with variables
*/
@Override
public URI expand(String uriTemplate, Object... uriVariables);
}Utilities for managing request expectations in REST client tests.
/**
* RequestExpectationManager that handles root URI expectations
* @since 1.4.0
*/
public class RootUriRequestExpectationManager implements RequestExpectationManager {
/**
* Create expectations for the given URI
*/
@Override
public ResponseActions expectRequest(ExpectedCount count, RequestMatcher matcher);
/**
* Verify that all expectations have been satisfied
*/
@Override
public void verify();
/**
* Reset all expectations
*/
@Override
public void reset();
}Integration utilities for HtmlUnit WebDriver testing.
/**
* WebClient that automatically configures localhost connections for testing
* @since 1.4.0
*/
public class LocalHostWebClient extends WebClient {
/**
* Create a LocalHostWebClient for the given Environment
*/
public LocalHostWebClient(Environment environment);
/**
* Create a LocalHostWebClient with SSL enabled
*/
public LocalHostWebClient(Environment environment, boolean enableSsl);
}
/**
* HtmlUnit WebDriver that automatically handles localhost connections
* @since 1.4.0
*/
public class LocalHostWebConnectionHtmlUnitDriver extends HtmlUnitDriver {
/**
* Create a driver for the given Environment
*/
public LocalHostWebConnectionHtmlUnitDriver(Environment environment);
/**
* Create a driver with the specified BrowserVersion
*/
public LocalHostWebConnectionHtmlUnitDriver(Environment environment, BrowserVersion browserVersion);
}Customizers for MockRestServiceServer and MockWebServiceServer.
/**
* Customizer for MockRestServiceServer
* @since 1.4.0
*/
public class MockServerRestTemplateCustomizer implements RestTemplateCustomizer {
/**
* Create a customizer for the given MockRestServiceServer
*/
public MockServerRestTemplateCustomizer(MockRestServiceServer server);
/**
* Customize the RestTemplate to use the mock server
*/
@Override
public void customize(RestTemplate restTemplate);
}
/**
* Customizer for MockWebServiceServer
* @since 1.4.0
*/
public class MockServerRestClientCustomizer {
/**
* Create a customizer for the given MockWebServiceServer
*/
public MockServerRestClientCustomizer(MockWebServiceServer server);
/**
* Customize the WebServiceTemplate to use the mock server
*/
public void customize(WebServiceTemplate webServiceTemplate);
}Advanced patterns for web testing with multiple scenarios.
Usage Examples:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AdvancedWebTestingTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void multipleRequestsWithDifferentAuth() {
// Test without authentication
ResponseEntity<String> publicResponse = restTemplate
.getForEntity("/api/public", String.class);
assertThat(publicResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
// Test with basic auth
TestRestTemplate authenticatedTemplate = restTemplate
.withBasicAuth("user", "password");
ResponseEntity<String> userResponse = authenticatedTemplate
.getForEntity("/api/user", String.class);
assertThat(userResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
// Test with admin auth
TestRestTemplate adminTemplate = restTemplate
.withBasicAuth("admin", "admin");
ResponseEntity<String> adminResponse = adminTemplate
.getForEntity("/api/admin", String.class);
assertThat(adminResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
}
@Test
void testWithCustomHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");
headers.set("User-Agent", "TestClient/1.0");
headers.set("X-API-Version", "v1");
HttpEntity<Void> entity = new HttpEntity<>(headers);
ResponseEntity<Map> response = restTemplate.exchange(
"/api/versioned", HttpMethod.GET, entity, Map.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).containsKey("version");
}
@Test
void testFileUpload() throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource("test-file.txt"));
body.add("description", "Test file upload");
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.postForEntity(
"/api/upload", entity, String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).contains("uploaded successfully");
}
}
// Configuration for customizing TestRestTemplate
@TestConfiguration
static class WebTestConfig {
@Bean
@Primary
public TestRestTemplate customTestRestTemplate(@LocalServerPort int port) {
TestRestTemplate template = new TestRestTemplate(
HttpClientOption.ENABLE_COOKIES,
HttpClientOption.ENABLE_REDIRECTS
);
// Configure root URI
template.setUriTemplateHandler(
new LocalHostUriTemplateHandler(new MockEnvironment()));
return template;
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-test