Migrate MockMvc tests to MockMvcTester

See gh-41198
This commit is contained in:
Stéphane Nicoll 2024-07-03 12:54:38 +02:00
parent e5859aedaf
commit 156237227c
77 changed files with 1050 additions and 1239 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -54,15 +54,12 @@ import org.springframework.security.config.BeanIds;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.filter.CompositeFilter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
/**
* Tests for {@link CloudFoundryActuatorAutoConfiguration}.
@ -109,8 +106,8 @@ class CloudFoundryActuatorAutoConfigurationTests {
.withPropertyValues("VCAP_APPLICATION:---", "vcap.application.application_id:my-app-id",
"vcap.application.cf_api:https://my-cloud-controller.com")
.run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/cloudfoundryapplication")).andExpect(header().string("Content-Type", V3_JSON));
MockMvcTester mvc = MockMvcTester.from(context);
assertThat(mvc.get().uri("/cloudfoundryapplication")).hasHeader("Content-Type", V3_JSON);
});
}

View File

@ -31,6 +31,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
@ -39,8 +40,6 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWit
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing {@link AuditEventsEndpoint}.
@ -53,13 +52,12 @@ class AuditEventsEndpointDocumentationTests extends MockMvcEndpointDocumentation
private AuditEventRepository repository;
@Test
void allAuditEvents() throws Exception {
void allAuditEvents() {
String queryTimestamp = "2017-11-07T09:37Z";
given(this.repository.find(any(), any(), any()))
.willReturn(List.of(new AuditEvent("alice", "logout", Collections.emptyMap())));
this.mockMvc.perform(get("/actuator/auditevents").param("after", queryTimestamp))
.andExpect(status().isOk())
.andDo(document("auditevents/all",
assertThat(this.mvc.get().uri("/actuator/auditevents").param("after", queryTimestamp)).hasStatusOk()
.apply(document("auditevents/all",
responseFields(fieldWithPath("events").description("An array of audit events."),
fieldWithPath("events.[].timestamp")
.description("The timestamp of when the event occurred."),
@ -68,17 +66,18 @@ class AuditEventsEndpointDocumentationTests extends MockMvcEndpointDocumentation
}
@Test
void filteredAuditEvents() throws Exception {
void filteredAuditEvents() {
OffsetDateTime now = OffsetDateTime.now();
String queryTimestamp = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(now);
given(this.repository.find("alice", now.toInstant(), "logout"))
.willReturn(List.of(new AuditEvent("alice", "logout", Collections.emptyMap())));
this.mockMvc
.perform(get("/actuator/auditevents").param("principal", "alice")
.param("after", queryTimestamp)
.param("type", "logout"))
.andExpect(status().isOk())
.andDo(document("auditevents/filtered",
assertThat(this.mvc.get()
.uri("/actuator/auditevents")
.param("principal", "alice")
.param("after", queryTimestamp)
.param("type", "logout"))
.hasStatusOk()
.apply(document("auditevents/filtered",
queryParameters(
parameterWithName("after").description(
"Restricts the events to those that occurred after the given time. Optional."),

View File

@ -33,12 +33,11 @@ import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.restdocs.payload.ResponseFieldsSnippet;
import org.springframework.util.CollectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing {@link BeansEndpoint}.
@ -48,7 +47,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class BeansEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void beans() throws Exception {
void beans() {
List<FieldDescriptor> beanFields = List.of(fieldWithPath("aliases").description("Names of any aliases."),
fieldWithPath("scope").description("Scope of the bean."),
fieldWithPath("type").description("Fully qualified type of the bean."),
@ -60,9 +59,8 @@ class BeansEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
fieldWithPath("contexts").description("Application contexts keyed by id."), parentIdField(),
fieldWithPath("contexts.*.beans").description("Beans in the application context keyed by name."))
.andWithPrefix("contexts.*.beans.*.", beanFields);
this.mockMvc.perform(get("/actuator/beans"))
.andExpect(status().isOk())
.andDo(document("beans",
assertThat(this.mvc.get().uri("/actuator/beans")).hasStatusOk()
.apply(document("beans",
preprocessResponse(
limit(this::isIndependentBean, "contexts", getApplicationContext().getId(), "beans")),
responseFields));

View File

@ -30,17 +30,16 @@ import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.request.ParameterDescriptor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link CachesEndpoint}
@ -59,10 +58,9 @@ class CachesEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
.optional());
@Test
void allCaches() throws Exception {
this.mockMvc.perform(get("/actuator/caches"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("caches/all",
void allCaches() {
assertThat(this.mvc.get().uri("/actuator/caches")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("caches/all",
responseFields(fieldWithPath("cacheManagers").description("Cache managers keyed by id."),
fieldWithPath("cacheManagers.*.caches")
.description("Caches in the application context keyed by name."))
@ -71,25 +69,23 @@ class CachesEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
}
@Test
void namedCache() throws Exception {
this.mockMvc.perform(get("/actuator/caches/cities"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("caches/named", queryParameters(queryParameters),
void namedCache() {
assertThat(this.mvc.get().uri("/actuator/caches/cities")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("caches/named", queryParameters(queryParameters),
responseFields(levelFields)));
}
@Test
void evictAllCaches() throws Exception {
this.mockMvc.perform(delete("/actuator/caches"))
.andExpect(status().isNoContent())
.andDo(MockMvcRestDocumentation.document("caches/evict-all"));
void evictAllCaches() {
assertThat(this.mvc.delete().uri("/actuator/caches")).hasStatus(HttpStatus.NO_CONTENT)
.apply(MockMvcRestDocumentation.document("caches/evict-all"));
}
@Test
void evictNamedCache() throws Exception {
this.mockMvc.perform(delete("/actuator/caches/countries?cacheManager=anotherCacheManager"))
.andExpect(status().isNoContent())
.andDo(MockMvcRestDocumentation.document("caches/evict-named", queryParameters(queryParameters)));
void evictNamedCache() {
assertThat(this.mvc.delete().uri("/actuator/caches/countries?cacheManager=anotherCacheManager"))
.hasStatus(HttpStatus.NO_CONTENT)
.apply(MockMvcRestDocumentation.document("caches/evict-named", queryParameters(queryParameters)));
}
@Configuration(proxyBeanMethods = false)

View File

@ -31,11 +31,10 @@ import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing {@link ConditionsReportEndpoint}.
@ -64,9 +63,8 @@ class ConditionsReportEndpointDocumentationTests extends MockMvcEndpointDocument
.optional());
FieldDescriptor unconditionalClassesField = fieldWithPath("contexts.*.unconditionalClasses")
.description("Names of unconditional auto-configuration classes if any.");
this.mockMvc.perform(get("/actuator/conditions"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("conditions",
assertThat(this.mvc.get().uri("/actuator/conditions")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("conditions",
preprocessResponse(limit("contexts", getApplicationContext().getId(), "positiveMatches"),
limit("contexts", getApplicationContext().getId(), "negativeMatches")),
responseFields(fieldWithPath("contexts").description("Application contexts keyed by id."))

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,12 +27,11 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing
@ -44,10 +43,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class ConfigurationPropertiesReportEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void configProps() throws Exception {
this.mockMvc.perform(get("/actuator/configprops"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("configprops/all",
void configProps() {
assertThat(this.mvc.get().uri("/actuator/configprops")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("configprops/all",
preprocessResponse(limit("contexts", getApplicationContext().getId(), "beans")),
responseFields(fieldWithPath("contexts").description("Application contexts keyed by id."),
fieldWithPath("contexts.*.beans.*")
@ -62,10 +60,9 @@ class ConfigurationPropertiesReportEndpointDocumentationTests extends MockMvcEnd
}
@Test
void configPropsFilterByPrefix() throws Exception {
this.mockMvc.perform(get("/actuator/configprops/spring.jackson"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("configprops/prefixed",
void configPropsFilterByPrefix() {
assertThat(this.mvc.get().uri("/actuator/configprops/spring.jackson")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("configprops/prefixed",
preprocessResponse(limit("contexts", getApplicationContext().getId(), "beans")),
responseFields(fieldWithPath("contexts").description("Application contexts keyed by id."),
fieldWithPath("contexts.*.beans.*")

View File

@ -44,13 +44,12 @@ import org.springframework.restdocs.operation.preprocess.OperationPreprocessor;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.replacePattern;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link EnvironmentEndpoint}.
@ -74,10 +73,9 @@ class EnvironmentEndpointDocumentationTests extends MockMvcEndpointDocumentation
.description("Name of the property source.");
@Test
void env() throws Exception {
this.mockMvc.perform(get("/actuator/env"))
.andExpect(status().isOk())
.andDo(document("env/all",
void env() {
assertThat(this.mvc.get().uri("/actuator/env")).hasStatusOk()
.apply(document("env/all",
preprocessResponse(
replacePattern(Pattern.compile(
"org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/"), ""),
@ -93,10 +91,9 @@ class EnvironmentEndpointDocumentationTests extends MockMvcEndpointDocumentation
}
@Test
void singlePropertyFromEnv() throws Exception {
this.mockMvc.perform(get("/actuator/env/com.example.cache.max-size"))
.andExpect(status().isOk())
.andDo(document("env/single",
void singlePropertyFromEnv() {
assertThat(this.mvc.get().uri("/actuator/env/com.example.cache.max-size")).hasStatusOk()
.apply(document("env/single",
preprocessResponse(replacePattern(Pattern
.compile("org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/"), "")),
responseFields(

View File

@ -35,10 +35,9 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.FieldDescriptor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link FlywayEndpoint}.
@ -48,10 +47,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class FlywayEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void flyway() throws Exception {
this.mockMvc.perform(get("/actuator/flyway"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("flyway",
void flyway() {
assertThat(this.mvc.get().uri("/actuator/flyway")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("flyway",
responseFields(fieldWithPath("contexts").description("Application contexts keyed by id"),
fieldWithPath("contexts.*.flywayBeans.*.migrations")
.description("Migrations performed by the Flyway instance, keyed by Flyway bean name."))

View File

@ -52,12 +52,11 @@ import org.springframework.http.MediaType;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.util.unit.DataSize;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link HealthEndpoint}.
@ -72,7 +71,7 @@ class HealthEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
subsectionWithPath("details").description("Details of the health of a specific part of the application."));
@Test
void health() throws Exception {
void health() {
FieldDescriptor status = fieldWithPath("status").description("Overall status of the application.");
FieldDescriptor components = fieldWithPath("components").description("The components that make up the health.");
FieldDescriptor componentStatus = fieldWithPath("components.*.status")
@ -84,24 +83,21 @@ class HealthEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
.description("Details of the health of a specific part of the application. "
+ "Presence is controlled by `management.endpoint.health.show-details`.")
.optional();
this.mockMvc.perform(get("/actuator/health").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("health",
assertThat(this.mvc.get().uri("/actuator/health").accept(MediaType.APPLICATION_JSON)).hasStatusOk()
.apply(document("health",
responseFields(status, components, componentStatus, nestedComponents, componentDetails)));
}
@Test
void healthComponent() throws Exception {
this.mockMvc.perform(get("/actuator/health/db").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("health/component", responseFields(componentFields)));
void healthComponent() {
assertThat(this.mvc.get().uri("/actuator/health/db").accept(MediaType.APPLICATION_JSON)).hasStatusOk()
.apply(document("health/component", responseFields(componentFields)));
}
@Test
void healthComponentInstance() throws Exception {
this.mockMvc.perform(get("/actuator/health/broker/us1").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(document("health/instance", responseFields(componentFields)));
void healthComponentInstance() {
assertThat(this.mvc.get().uri("/actuator/health/broker/us1").accept(MediaType.APPLICATION_JSON)).hasStatusOk()
.apply(document("health/instance", responseFields(componentFields)));
}
@Configuration(proxyBeanMethods = false)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -32,9 +32,8 @@ import org.springframework.restdocs.cli.CurlRequestSnippet;
import org.springframework.restdocs.operation.Operation;
import org.springframework.util.FileCopyUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link HeapDumpWebEndpoint}.
@ -44,10 +43,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class HeapDumpWebEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void heapDump() throws Exception {
this.mockMvc.perform(get("/actuator/heapdump"))
.andExpect(status().isOk())
.andDo(document("heapdump", new CurlRequestSnippet(CliDocumentation.multiLineFormat()) {
void heapDump() {
assertThat(this.mvc.get().uri("/actuator/heapdump")).hasStatusOk()
.apply(document("heapdump", new CurlRequestSnippet(CliDocumentation.multiLineFormat()) {
@Override
protected Map<String, Object> createModel(Operation operation) {

View File

@ -42,13 +42,12 @@ import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing {@link HttpExchangesEndpoint}.
@ -61,7 +60,7 @@ class HttpExchangesEndpointDocumentationTests extends MockMvcEndpointDocumentati
private HttpExchangeRepository repository;
@Test
void httpExchanges() throws Exception {
void httpExchanges() {
RecordableHttpRequest request = mock(RecordableHttpRequest.class);
given(request.getUri()).willReturn(URI.create("https://api.example.com"));
given(request.getMethod()).willReturn("GET");
@ -79,9 +78,8 @@ class HttpExchangesEndpointDocumentationTests extends MockMvcEndpointDocumentati
HttpExchange exchange = HttpExchange.start(start, request)
.finish(end, response, () -> principal, () -> UUID.randomUUID().toString(), EnumSet.allOf(Include.class));
given(this.repository.findAll()).willReturn(List.of(exchange));
this.mockMvc.perform(get("/actuator/httpexchanges"))
.andExpect(status().isOk())
.andDo(document("httpexchanges", responseFields(
assertThat(this.mvc.get().uri("/actuator/httpexchanges")).hasStatusOk()
.apply(document("httpexchanges", responseFields(
fieldWithPath("exchanges").description("An array of HTTP request-response exchanges."),
fieldWithPath("exchanges.[].timestamp").description("Timestamp of when the exchange occurred."),
fieldWithPath("exchanges.[].principal").description("Principal of the exchange, if any.")

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -34,11 +34,10 @@ import org.springframework.context.annotation.Import;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.payload.PayloadDocumentation.beneathPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link InfoEndpoint}.
@ -48,10 +47,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class InfoEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void info() throws Exception {
this.mockMvc.perform(get("/actuator/info"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("info",
void info() {
assertThat(this.mvc.get().uri("/actuator/info")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("info",
responseFields(beneathPath("git"),
fieldWithPath("branch").description("Name of the Git branch, if any."),
fieldWithPath("commit").description("Details of the Git commit, if any."),

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,13 +22,12 @@ import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.graph.IntegrationGraphServer;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for generating documentation describing the {@link IntegrationGraphEndpoint}.
@ -38,17 +37,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class IntegrationGraphEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void graph() throws Exception {
this.mockMvc.perform(get("/actuator/integrationgraph"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("integrationgraph/graph"));
void graph() {
assertThat(this.mvc.get().uri("/actuator/integrationgraph")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("integrationgraph/graph"));
}
@Test
void rebuild() throws Exception {
this.mockMvc.perform(post("/actuator/integrationgraph"))
.andExpect(status().isNoContent())
.andDo(MockMvcRestDocumentation.document("integrationgraph/rebuild"));
void rebuild() {
assertThat(this.mvc.post().uri("/actuator/integrationgraph")).hasStatus(HttpStatus.NO_CONTENT)
.apply(MockMvcRestDocumentation.document("integrationgraph/rebuild"));
}
@Configuration(proxyBeanMethods = false)

View File

@ -32,10 +32,9 @@ import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link LiquibaseEndpoint}.
@ -45,12 +44,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class LiquibaseEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void liquibase() throws Exception {
void liquibase() {
FieldDescriptor changeSetsField = fieldWithPath("contexts.*.liquibaseBeans.*.changeSets")
.description("Change sets made by the Liquibase beans, keyed by bean name.");
this.mockMvc.perform(get("/actuator/liquibase"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("liquibase",
assertThat(this.mvc.get().uri("/actuator/liquibase")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("liquibase",
responseFields(fieldWithPath("contexts").description("Application contexts keyed by id"),
changeSetsField)
.andWithPrefix("contexts.*.liquibaseBeans.*.changeSets[].", getChangeSetFieldDescriptors())

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,11 +23,11 @@ import org.springframework.boot.logging.LogFile;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for generating documentation describing the {@link LogFileWebEndpoint}.
@ -37,17 +37,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class LogFileWebEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void logFile() throws Exception {
this.mockMvc.perform(get("/actuator/logfile"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("logfile/entire"));
void logFile() {
assertThat(this.mvc.get().uri("/actuator/logfile")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("logfile/entire"));
}
@Test
void logFileRange() throws Exception {
this.mockMvc.perform(get("/actuator/logfile").header("Range", "bytes=0-1023"))
.andExpect(status().isPartialContent())
.andDo(MockMvcRestDocumentation.document("logfile/range"));
void logFileRange() {
assertThat(this.mvc.get().uri("/actuator/logfile").header("Range", "bytes=0-1023"))
.hasStatus(HttpStatus.PARTIAL_CONTENT)
.apply(MockMvcRestDocumentation.document("logfile/range"));
}
@Configuration(proxyBeanMethods = false)

View File

@ -33,19 +33,18 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link LoggersEndpoint}.
@ -70,14 +69,13 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
private LoggerGroups loggerGroups;
@Test
void allLoggers() throws Exception {
void allLoggers() {
given(this.loggingSystem.getSupportedLogLevels()).willReturn(EnumSet.allOf(LogLevel.class));
given(this.loggingSystem.getLoggerConfigurations())
.willReturn(List.of(new LoggerConfiguration("ROOT", LogLevel.INFO, LogLevel.INFO),
new LoggerConfiguration("com.example", LogLevel.DEBUG, LogLevel.DEBUG)));
this.mockMvc.perform(get("/actuator/loggers"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("loggers/all",
assertThat(this.mvc.get().uri("/actuator/loggers")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("loggers/all",
responseFields(fieldWithPath("levels").description("Levels support by the logging system."),
fieldWithPath("loggers").description("Loggers keyed by name."),
fieldWithPath("groups").description("Logger groups keyed by name"))
@ -86,31 +84,30 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
}
@Test
void logger() throws Exception {
void logger() {
given(this.loggingSystem.getLoggerConfiguration("com.example"))
.willReturn(new LoggerConfiguration("com.example", LogLevel.INFO, LogLevel.INFO));
this.mockMvc.perform(get("/actuator/loggers/com.example"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("loggers/single", responseFields(levelFields)));
assertThat(this.mvc.get().uri("/actuator/loggers/com.example")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("loggers/single", responseFields(levelFields)));
}
@Test
void loggerGroups() throws Exception {
void loggerGroups() {
this.loggerGroups.get("test").configureLogLevel(LogLevel.INFO, (member, level) -> {
});
this.mockMvc.perform(get("/actuator/loggers/test"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("loggers/group", responseFields(groupLevelFields)));
assertThat(this.mvc.get().uri("/actuator/loggers/test")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("loggers/group", responseFields(groupLevelFields)));
resetLogger();
}
@Test
void setLogLevel() throws Exception {
this.mockMvc
.perform(post("/actuator/loggers/com.example").content("{\"configuredLevel\":\"debug\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNoContent())
.andDo(MockMvcRestDocumentation.document("loggers/set",
void setLogLevel() {
assertThat(this.mvc.post()
.uri("/actuator/loggers/com.example")
.content("{\"configuredLevel\":\"debug\"}")
.contentType(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.NO_CONTENT)
.apply(MockMvcRestDocumentation.document("loggers/set",
requestFields(fieldWithPath("configuredLevel")
.description("Level for the logger. May be omitted to clear the level.")
.optional())));
@ -118,12 +115,13 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
}
@Test
void setLogLevelOfLoggerGroup() throws Exception {
this.mockMvc
.perform(post("/actuator/loggers/test").content("{\"configuredLevel\":\"debug\"}")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNoContent())
.andDo(MockMvcRestDocumentation.document("loggers/setGroup",
void setLogLevelOfLoggerGroup() {
assertThat(this.mvc.post()
.uri("/actuator/loggers/test")
.content("{\"configuredLevel\":\"debug\"}")
.contentType(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.NO_CONTENT)
.apply(MockMvcRestDocumentation.document("loggers/setGroup",
requestFields(fieldWithPath("configuredLevel")
.description("Level for the logger group. May be omitted to clear the level of the loggers.")
.optional())));
@ -138,11 +136,12 @@ class LoggersEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
}
@Test
void clearLogLevel() throws Exception {
this.mockMvc
.perform(post("/actuator/loggers/com.example").content("{}").contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNoContent())
.andDo(MockMvcRestDocumentation.document("loggers/clear"));
void clearLogLevel() {
assertThat(this.mvc.post()
.uri("/actuator/loggers/com.example")
.content("{}")
.contentType(MediaType.APPLICATION_JSON)).hasStatus(HttpStatus.NO_CONTENT)
.apply(MockMvcRestDocumentation.document("loggers/clear"));
then(this.loggingSystem).should().setLogLevel("com.example", null);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,13 +26,12 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link MetricsEndpoint}.
@ -42,18 +41,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class MetricsEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void metricNames() throws Exception {
this.mockMvc.perform(get("/actuator/metrics"))
.andExpect(status().isOk())
.andDo(document("metrics/names",
void metricNames() {
assertThat(this.mvc.get().uri("/actuator/metrics")).hasStatusOk()
.apply(document("metrics/names",
responseFields(fieldWithPath("names").description("Names of the known metrics."))));
}
@Test
void metric() throws Exception {
this.mockMvc.perform(get("/actuator/metrics/jvm.memory.max"))
.andExpect(status().isOk())
.andDo(document("metrics/metric",
void metric() {
assertThat(this.mvc.get().uri("/actuator/metrics/jvm.memory.max")).hasStatusOk()
.apply(document("metrics/metric",
responseFields(fieldWithPath("name").description("Name of the metric"),
fieldWithPath("description").description("Description of the metric"),
fieldWithPath("baseUnit").description("Base unit of the metric"),
@ -67,12 +64,12 @@ class MetricsEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
}
@Test
void metricWithTags() throws Exception {
this.mockMvc
.perform(get("/actuator/metrics/jvm.memory.max").param("tag", "area:nonheap")
.param("tag", "id:Compressed Class Space"))
.andExpect(status().isOk())
.andDo(document("metrics/metric-with-tags", queryParameters(
void metricWithTags() {
assertThat(this.mvc.get()
.uri("/actuator/metrics/jvm.memory.max")
.param("tag", "area:nonheap")
.param("tag", "id:Compressed Class Space")).hasStatusOk()
.apply(document("metrics/metric-with-tags", queryParameters(
parameterWithName("tag").description("A tag to use for drill-down in the form `name:value`."))));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,13 +24,12 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.restdocs.RestDocumentationContextProvider;
import org.springframework.restdocs.RestDocumentationExtension;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.context.WebApplicationContext;
/**
* Abstract base class for tests that generate endpoint documentation using Spring REST
* Docs and {@link MockMvc}.
* Docs and {@link MockMvcTester}.
*
* @author Andy Wilkinson
*/
@ -38,16 +37,17 @@ import org.springframework.web.context.WebApplicationContext;
@SpringBootTest
public abstract class MockMvcEndpointDocumentationTests extends AbstractEndpointDocumentationTests {
protected MockMvc mockMvc;
protected MockMvcTester mvc;
@Autowired
private WebApplicationContext applicationContext;
@BeforeEach
void setup(RestDocumentationContextProvider restDocumentation) {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.applicationContext)
.apply(MockMvcRestDocumentation.documentationConfiguration(restDocumentation).uris())
.build();
this.mvc = MockMvcTester.from(this.applicationContext,
(builder) -> builder
.apply(MockMvcRestDocumentation.documentationConfiguration(restDocumentation).uris())
.build());
}
protected WebApplicationContext getApplicationContext() {

View File

@ -30,12 +30,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link PrometheusScrapeEndpoint}.
@ -46,25 +44,28 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class PrometheusScrapeEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void prometheus() throws Exception {
this.mockMvc.perform(get("/actuator/prometheus")).andExpect(status().isOk()).andDo(document("prometheus/all"));
void prometheus() {
assertThat(this.mvc.get().uri("/actuator/prometheus")).hasStatusOk().apply(document("prometheus/all"));
}
@Test
void prometheusOpenmetrics() throws Exception {
this.mockMvc.perform(get("/actuator/prometheus").accept(TextFormat.CONTENT_TYPE_OPENMETRICS_100))
.andExpect(status().isOk())
.andExpect(header().string("Content-Type", "application/openmetrics-text;version=1.0.0;charset=utf-8"))
.andDo(document("prometheus/openmetrics"));
void prometheusOpenmetrics() {
assertThat(this.mvc.get().uri("/actuator/prometheus").accept(TextFormat.CONTENT_TYPE_OPENMETRICS_100))
.satisfies((result) -> {
assertThat(result).hasStatusOk()
.headers()
.hasValue("Content-Type", "application/openmetrics-text;version=1.0.0;charset=utf-8");
assertThat(result).apply(document("prometheus/openmetrics"));
});
}
@Test
void filteredPrometheus() throws Exception {
this.mockMvc
.perform(get("/actuator/prometheus").param("includedNames",
"jvm_memory_used_bytes,jvm_memory_committed_bytes"))
.andExpect(status().isOk())
.andDo(document("prometheus/names",
void filteredPrometheus() {
assertThat(this.mvc.get()
.uri("/actuator/prometheus")
.param("includedNames", "jvm_memory_used_bytes,jvm_memory_committed_bytes"))
.hasStatusOk()
.apply(document("prometheus/names",
queryParameters(parameterWithName("includedNames")
.description("Restricts the samples to those that match the names. Optional.")
.optional())));

View File

@ -27,12 +27,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the
@ -44,27 +42,30 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class PrometheusSimpleclientScrapeEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void prometheus() throws Exception {
this.mockMvc.perform(get("/actuator/prometheus"))
.andExpect(status().isOk())
.andDo(document("prometheus-simpleclient/all"));
void prometheus() {
assertThat(this.mvc.get().uri("/actuator/prometheus")).hasStatusOk()
.apply(document("prometheus-simpleclient/all"));
}
@Test
void prometheusOpenmetrics() throws Exception {
this.mockMvc.perform(get("/actuator/prometheus").accept(TextFormat.CONTENT_TYPE_OPENMETRICS_100))
.andExpect(status().isOk())
.andExpect(header().string("Content-Type", "application/openmetrics-text;version=1.0.0;charset=utf-8"))
.andDo(document("prometheus-simpleclient/openmetrics"));
void prometheusOpenmetrics() {
assertThat(this.mvc.get().uri("/actuator/prometheus").accept(TextFormat.CONTENT_TYPE_OPENMETRICS_100))
.satisfies((result) -> {
assertThat(result).hasStatusOk()
.headers()
.hasValue("Content-Type", "application/openmetrics-text;version=1.0.0;charset=utf-8");
assertThat(result).apply(document("prometheus-simpleclient/openmetrics"));
});
}
@Test
void filteredPrometheus() throws Exception {
this.mockMvc
.perform(get("/actuator/prometheus").param("includedNames",
"jvm_memory_used_bytes,jvm_memory_committed_bytes"))
.andExpect(status().isOk())
.andDo(document("prometheus-simpleclient/names",
void filteredPrometheus() {
assertThat(this.mvc.get()
.uri("/actuator/prometheus")
.param("includedNames", "jvm_memory_used_bytes,jvm_memory_committed_bytes"))
.hasStatusOk()
.apply(document("prometheus-simpleclient/names",
queryParameters(parameterWithName("includedNames")
.description("Restricts the samples to those that match the names. Optional.")
.optional())));

View File

@ -64,6 +64,7 @@ import org.springframework.scheduling.quartz.DelegatingJob;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
@ -71,8 +72,6 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWit
import static org.springframework.restdocs.payload.PayloadDocumentation.relaxedResponseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link QuartzEndpoint}.
@ -186,9 +185,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
void quartzReport() throws Exception {
mockJobs(jobOne, jobTwo, jobThree);
mockTriggers(cronTrigger, simpleTrigger, calendarIntervalTrigger, dailyTimeIntervalTrigger);
this.mockMvc.perform(get("/actuator/quartz"))
.andExpect(status().isOk())
.andDo(document("quartz/report",
assertThat(this.mvc.get().uri("/actuator/quartz")).hasStatusOk()
.apply(document("quartz/report",
responseFields(fieldWithPath("jobs.groups").description("An array of job group names."),
fieldWithPath("triggers.groups").description("An array of trigger group names."))));
}
@ -196,9 +194,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzJobs() throws Exception {
mockJobs(jobOne, jobTwo, jobThree);
this.mockMvc.perform(get("/actuator/quartz/jobs"))
.andExpect(status().isOk())
.andDo(document("quartz/jobs",
assertThat(this.mvc.get().uri("/actuator/quartz/jobs")).hasStatusOk()
.apply(document("quartz/jobs",
responseFields(fieldWithPath("groups").description("Job groups keyed by name."),
fieldWithPath("groups.*.jobs").description("An array of job names."))));
}
@ -206,9 +203,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzTriggers() throws Exception {
mockTriggers(cronTrigger, simpleTrigger, calendarIntervalTrigger, dailyTimeIntervalTrigger);
this.mockMvc.perform(get("/actuator/quartz/triggers"))
.andExpect(status().isOk())
.andDo(document("quartz/triggers",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers")).hasStatusOk()
.apply(document("quartz/triggers",
responseFields(fieldWithPath("groups").description("Trigger groups keyed by name."),
fieldWithPath("groups.*.paused").description("Whether this trigger group is paused."),
fieldWithPath("groups.*.triggers").description("An array of trigger names."))));
@ -217,9 +213,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzJobGroup() throws Exception {
mockJobs(jobOne, jobTwo, jobThree);
this.mockMvc.perform(get("/actuator/quartz/jobs/samples"))
.andExpect(status().isOk())
.andDo(document("quartz/job-group", responseFields(fieldWithPath("group").description("Name of the group."),
assertThat(this.mvc.get().uri("/actuator/quartz/jobs/samples")).hasStatusOk()
.apply(document("quartz/job-group", responseFields(fieldWithPath("group").description("Name of the group."),
fieldWithPath("jobs").description("Job details keyed by name."),
fieldWithPath("jobs.*.className").description("Fully qualified name of the job implementation."))));
}
@ -250,9 +245,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
given(customTrigger.getPreviousFireTime()).willReturn(fromUtc("2020-07-14T16:00:00Z"));
given(customTrigger.getNextFireTime()).willReturn(fromUtc("2021-07-14T16:00:00Z"));
mockTriggers(cron, simple, calendarInterval, tueThuTrigger, customTrigger);
this.mockMvc.perform(get("/actuator/quartz/triggers/tests"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-group",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/tests")).hasStatusOk()
.apply(document("quartz/trigger-group",
responseFields(fieldWithPath("group").description("Name of the group."),
fieldWithPath("paused").description("Whether the group is paused."),
fieldWithPath("triggers.cron").description("Cron triggers keyed by name, if any."),
@ -281,9 +275,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
mockTriggers(firstTrigger, secondTrigger);
given(this.scheduler.getTriggersOfJob(jobOne.getKey()))
.willAnswer((invocation) -> List.of(firstTrigger, secondTrigger));
this.mockMvc.perform(get("/actuator/quartz/jobs/samples/jobOne"))
.andExpect(status().isOk())
.andDo(document("quartz/job-details", responseFields(
assertThat(this.mvc.get().uri("/actuator/quartz/jobs/samples/jobOne")).hasStatusOk()
.apply(document("quartz/job-details", responseFields(
fieldWithPath("group").description("Name of the group."),
fieldWithPath("name").description("Name of the job."),
fieldWithPath("description").description("Description of the job, if any."),
@ -301,9 +294,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzTriggerCommon() throws Exception {
setupTriggerDetails(cronTrigger.getTriggerBuilder(), TriggerState.NORMAL);
this.mockMvc.perform(get("/actuator/quartz/triggers/samples/example"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-details-common", responseFields(commonCronDetails).and(subsectionWithPath(
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/samples/example")).hasStatusOk()
.apply(document("quartz/trigger-details-common", responseFields(commonCronDetails).and(subsectionWithPath(
"calendarInterval")
.description(
"Calendar time interval trigger details, if any. Present when `type` is `calendarInterval`.")
@ -330,9 +322,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzTriggerCron() throws Exception {
setupTriggerDetails(cronTrigger.getTriggerBuilder(), TriggerState.NORMAL);
this.mockMvc.perform(get("/actuator/quartz/triggers/samples/example"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-details-cron",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/samples/example")).hasStatusOk()
.apply(document("quartz/trigger-details-cron",
relaxedResponseFields(fieldWithPath("cron").description("Cron trigger specific details."))
.andWithPrefix("cron.", cronTriggerSummary)));
}
@ -340,9 +331,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzTriggerSimple() throws Exception {
setupTriggerDetails(simpleTrigger.getTriggerBuilder(), TriggerState.NORMAL);
this.mockMvc.perform(get("/actuator/quartz/triggers/samples/example"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-details-simple",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/samples/example")).hasStatusOk()
.apply(document("quartz/trigger-details-simple",
relaxedResponseFields(fieldWithPath("simple").description("Simple trigger specific details."))
.andWithPrefix("simple.", simpleTriggerSummary)
.and(repeatCount("simple."), timesTriggered("simple."))));
@ -351,9 +341,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzTriggerCalendarInterval() throws Exception {
setupTriggerDetails(calendarIntervalTrigger.getTriggerBuilder(), TriggerState.NORMAL);
this.mockMvc.perform(get("/actuator/quartz/triggers/samples/example"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-details-calendar-interval",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/samples/example")).hasStatusOk()
.apply(document("quartz/trigger-details-calendar-interval",
relaxedResponseFields(fieldWithPath("calendarInterval")
.description("Calendar interval trigger specific details."))
.andWithPrefix("calendarInterval.", calendarIntervalTriggerSummary)
@ -368,9 +357,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
@Test
void quartzTriggerDailyTimeInterval() throws Exception {
setupTriggerDetails(dailyTimeIntervalTrigger.getTriggerBuilder(), TriggerState.PAUSED);
this.mockMvc.perform(get("/actuator/quartz/triggers/samples/example"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-details-daily-time-interval",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/samples/example")).hasStatusOk()
.apply(document("quartz/trigger-details-daily-time-interval",
relaxedResponseFields(fieldWithPath("dailyTimeInterval")
.description("Daily time interval trigger specific details."))
.andWithPrefix("dailyTimeInterval.", dailyTimeIntervalTriggerSummary)
@ -391,9 +379,8 @@ class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests
given(trigger.getNextFireTime()).willReturn(fromUtc("2020-12-07T03:00:00Z"));
given(this.scheduler.getTriggerState(trigger.getKey())).willReturn(TriggerState.NORMAL);
mockTriggers(trigger);
this.mockMvc.perform(get("/actuator/quartz/triggers/samples/example"))
.andExpect(status().isOk())
.andDo(document("quartz/trigger-details-custom",
assertThat(this.mvc.get().uri("/actuator/quartz/triggers/samples/example")).hasStatusOk()
.apply(document("quartz/trigger-details-custom",
relaxedResponseFields(fieldWithPath("custom").description("Custom trigger specific details."))
.andWithPrefix("custom.", customTriggerSummary)));
}

View File

@ -27,10 +27,9 @@ import org.springframework.context.annotation.Import;
import org.springframework.core.io.ResourceLoader;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link SbomEndpoint}.
@ -40,18 +39,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class SbomEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void sbom() throws Exception {
this.mockMvc.perform(get("/actuator/sbom"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("sbom",
void sbom() {
assertThat(this.mvc.get().uri("/actuator/sbom")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("sbom",
responseFields(fieldWithPath("ids").description("An array of available SBOM ids."))));
}
@Test
void sboms() throws Exception {
this.mockMvc.perform(get("/actuator/sbom/application"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("sbom/id"));
void sboms() {
assertThat(this.mvc.get().uri("/actuator/sbom/application")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("sbom/id"));
}
@Configuration(proxyBeanMethods = false)

View File

@ -34,13 +34,12 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskHolder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.replacePattern;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link ScheduledTasksEndpoint}.
@ -50,10 +49,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class ScheduledTasksEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void scheduledTasks() throws Exception {
this.mockMvc.perform(get("/actuator/scheduledtasks"))
.andExpect(status().isOk())
.andDo(document("scheduled-tasks",
void scheduledTasks() {
assertThat(this.mvc.get().uri("/actuator/scheduledtasks")).hasStatusOk()
.apply(document("scheduled-tasks",
preprocessResponse(replacePattern(
Pattern.compile("org.*\\.ScheduledTasksEndpointDocumentationTests\\$TestConfiguration"),
"com.example.Processor")),

View File

@ -30,12 +30,14 @@ import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.MapSession;
import org.springframework.session.Session;
import org.springframework.test.context.TestPropertySource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
@ -43,9 +45,6 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWit
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.queryParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link ShutdownEndpoint}.
@ -77,33 +76,31 @@ class SessionsEndpointDocumentationTests extends MockMvcEndpointDocumentationTes
private FindByIndexNameSessionRepository<Session> sessionRepository;
@Test
void sessionsForUsername() throws Exception {
void sessionsForUsername() {
Map<String, Session> sessions = new HashMap<>();
sessions.put(sessionOne.getId(), sessionOne);
sessions.put(sessionTwo.getId(), sessionTwo);
sessions.put(sessionThree.getId(), sessionThree);
given(this.sessionRepository.findByPrincipalName("alice")).willReturn(sessions);
this.mockMvc.perform(get("/actuator/sessions").param("username", "alice"))
.andExpect(status().isOk())
.andDo(document("sessions/username",
assertThat(this.mvc.get().uri("/actuator/sessions").param("username", "alice")).hasStatusOk()
.apply(document("sessions/username",
responseFields(fieldWithPath("sessions").description("Sessions for the given username."))
.andWithPrefix("sessions.[].", sessionFields),
queryParameters(parameterWithName("username").description("Name of the user."))));
}
@Test
void sessionWithId() throws Exception {
void sessionWithId() {
given(this.sessionRepository.findById(sessionTwo.getId())).willReturn(sessionTwo);
this.mockMvc.perform(get("/actuator/sessions/{id}", sessionTwo.getId()))
.andExpect(status().isOk())
.andDo(document("sessions/id", responseFields(sessionFields)));
assertThat(this.mvc.get().uri("/actuator/sessions/{id}", sessionTwo.getId())).hasStatusOk()
.apply(document("sessions/id", responseFields(sessionFields)));
}
@Test
void deleteASession() throws Exception {
this.mockMvc.perform(delete("/actuator/sessions/{id}", sessionTwo.getId()))
.andExpect(status().isNoContent())
.andDo(document("sessions/delete"));
void deleteASession() {
assertThat(this.mvc.delete().uri("/actuator/sessions/{id}", sessionTwo.getId()))
.hasStatus(HttpStatus.NO_CONTENT)
.apply(document("sessions/delete"));
then(this.sessionRepository).should().deleteById(sessionTwo.getId());
}

View File

@ -25,10 +25,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing the {@link ShutdownEndpoint}.
@ -38,10 +37,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class ShutdownEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void shutdown() throws Exception {
this.mockMvc.perform(post("/actuator/shutdown"))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("shutdown", responseFields(
void shutdown() {
assertThat(this.mvc.post().uri("/actuator/shutdown")).hasStatusOk()
.apply(MockMvcRestDocumentation.document("shutdown", responseFields(
fieldWithPath("message").description("Message describing the result of the request."))));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,11 +30,9 @@ import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.restdocs.payload.PayloadDocumentation;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing {@link StartupEndpoint}.
@ -55,17 +53,15 @@ class StartupEndpointDocumentationTests extends MockMvcEndpointDocumentationTest
}
@Test
void startupSnapshot() throws Exception {
this.mockMvc.perform(get("/actuator/startup"))
.andExpect(status().isOk())
.andDo(document("startup-snapshot", PayloadDocumentation.responseFields(responseFields())));
void startupSnapshot() {
assertThat(this.mvc.get().uri("/actuator/startup")).hasStatusOk()
.apply(document("startup-snapshot", PayloadDocumentation.responseFields(responseFields())));
}
@Test
void startup() throws Exception {
this.mockMvc.perform(post("/actuator/startup"))
.andExpect(status().isOk())
.andDo(document("startup", PayloadDocumentation.responseFields(responseFields())));
void startup() {
assertThat(this.mvc.post().uri("/actuator/startup")).hasStatusOk()
.apply(document("startup", PayloadDocumentation.responseFields(responseFields())));
}
private FieldDescriptor[] responseFields() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -31,12 +31,11 @@ import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.operation.preprocess.ContentModifyingOperationPreprocessor;
import org.springframework.restdocs.payload.JsonFieldType;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for generating documentation describing {@link ThreadDumpEndpoint}.
@ -46,7 +45,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class ThreadDumpEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
@Test
void jsonThreadDump() throws Exception {
void jsonThreadDump() {
ReentrantLock lock = new ReentrantLock();
CountDownLatch latch = new CountDownLatch(1);
new Thread(() -> {
@ -63,9 +62,8 @@ class ThreadDumpEndpointDocumentationTests extends MockMvcEndpointDocumentationT
Thread.currentThread().interrupt();
}
}).start();
this.mockMvc.perform(get("/actuator/threaddump").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation
assertThat(this.mvc.get().uri("/actuator/threaddump").accept(MediaType.APPLICATION_JSON)).hasStatusOk()
.apply(MockMvcRestDocumentation
.document("threaddump/json", preprocessResponse(limit("threads")), responseFields(
fieldWithPath("threads").description("JVM's threads."),
fieldWithPath("threads.[].blockedCount")
@ -178,10 +176,9 @@ class ThreadDumpEndpointDocumentationTests extends MockMvcEndpointDocumentationT
}
@Test
void textThreadDump() throws Exception {
this.mockMvc.perform(get("/actuator/threaddump").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andDo(MockMvcRestDocumentation.document("threaddump/text",
void textThreadDump() {
assertThat(this.mvc.get().uri("/actuator/threaddump").accept(MediaType.TEXT_PLAIN)).hasStatusOk()
.apply(MockMvcRestDocumentation.document("threaddump/text",
preprocessResponse(new ContentModifyingOperationPreprocessor((bytes, mediaType) -> {
String content = new String(bytes, StandardCharsets.UTF_8);
int mainThreadIndex = content.indexOf("\"main\" - Thread");

View File

@ -37,19 +37,17 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.web.bind.annotation.GetMapping;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests for the Actuator's MVC {@link ControllerEndpoint controller
@ -69,16 +67,16 @@ class ControllerEndpointWebMvcIntegrationTests {
}
@Test
void endpointsAreSecureByDefault() throws Exception {
void endpointsAreSecureByDefault() {
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class, ExampleController.class);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/actuator/example").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized());
MockMvcTester mvc = createSecureMockMvcTester();
assertThat(mvc.get().uri("/actuator/example").accept(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.UNAUTHORIZED);
}
@Test
void endpointsCanBeAccessed() throws Exception {
void endpointsCanBeAccessed() {
TestSecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
this.context = new AnnotationConfigServletWebApplicationContext();
@ -86,22 +84,23 @@ class ControllerEndpointWebMvcIntegrationTests {
TestPropertyValues
.of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*")
.applyTo(this.context);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/management/example")).andExpect(status().isOk());
MockMvcTester mvc = createSecureMockMvcTester();
assertThat(mvc.get().uri("/management/example")).hasStatusOk();
}
private MockMvc createSecureMockMvc() {
return doCreateMockMvc(springSecurity());
private MockMvcTester createSecureMockMvcTester() {
return doCreateMockMvcTester(springSecurity());
}
private MockMvc doCreateMockMvc(MockMvcConfigurer... configurers) {
private MockMvcTester doCreateMockMvcTester(MockMvcConfigurer... configurers) {
this.context.setServletContext(new MockServletContext());
this.context.refresh();
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.context);
for (MockMvcConfigurer configurer : configurers) {
builder.apply(configurer);
}
return builder.build();
return MockMvcTester.from(this.context, (builder) -> {
for (MockMvcConfigurer configurer : configurers) {
builder.apply(configurer);
}
return builder.build();
});
}
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.boot.actuate.autoconfigure.integrationtest;
import org.assertj.core.api.ThrowingConsumer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.beans.BeansEndpointAutoConfiguration;
@ -32,14 +33,12 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.http.HttpHeaders;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.test.web.servlet.assertj.MvcTestResult;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.options;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for the MVC actuator endpoints' CORS support
@ -60,21 +59,22 @@ class WebMvcEndpointCorsIntegrationTests {
@Test
void corsIsDisabledByDefault() {
this.contextRunner.run(withMockMvc((mockMvc) -> mockMvc
.perform(options("/actuator/beans").header("Origin", "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN))));
this.contextRunner.run(withMockMvc((mvc) -> assertThat(mvc.options()
.uri("/actuator/beans")
.header("Origin", "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.doesNotContainHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)));
}
@Test
void settingAllowedOriginsEnablesCors() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com")
.run(withMockMvc((mockMvc) -> {
mockMvc
.perform(options("/actuator/beans").header("Origin", "bar.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(status().isForbidden());
performAcceptedCorsRequest(mockMvc);
.run(withMockMvc((mvc) -> {
assertThat(mvc.options()
.uri("/actuator/beans")
.header("Origin", "bar.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")).hasStatus(HttpStatus.FORBIDDEN);
performAcceptedCorsRequest(mvc);
}));
}
@ -83,20 +83,22 @@ class WebMvcEndpointCorsIntegrationTests {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origin-patterns:*.example.com",
"management.endpoints.web.cors.allow-credentials:true")
.run(withMockMvc((mockMvc) -> {
mockMvc
.perform(options("/actuator/beans").header("Origin", "bar.example.org")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(status().isForbidden());
performAcceptedCorsRequest(mockMvc);
.run(withMockMvc((mvc) -> {
assertThat(mvc.options()
.uri("/actuator/beans")
.header("Origin", "bar.example.org")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")).hasStatus(HttpStatus.FORBIDDEN);
performAcceptedCorsRequest(mvc);
}));
}
@Test
void maxAgeDefaultsTo30Minutes() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com")
.run(withMockMvc((mockMvc) -> performAcceptedCorsRequest(mockMvc)
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1800"))));
.run(withMockMvc((mvc) -> {
MvcTestResult result = performAcceptedCorsRequest(mvc);
assertThat(result).hasHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "1800");
}));
}
@Test
@ -104,20 +106,20 @@ class WebMvcEndpointCorsIntegrationTests {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com",
"management.endpoints.web.cors.max-age: 2400")
.run(withMockMvc((mockMvc) -> performAcceptedCorsRequest(mockMvc)
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "2400"))));
.run(withMockMvc((mvc) -> {
MvcTestResult result = performAcceptedCorsRequest(mvc);
assertThat(result).hasHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE, "2400");
}));
}
@Test
void requestsWithDisallowedHeadersAreRejected() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com")
.run(withMockMvc((mockMvc) ->
mockMvc
.perform(options("/actuator/beans").header("Origin", "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Alpha"))
.andExpect(status().isForbidden())));
.run(withMockMvc((mvc) -> assertThat(mvc.options()
.uri("/actuator/beans")
.header("Origin", "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Alpha")).hasStatus(HttpStatus.FORBIDDEN)));
}
@Test
@ -125,21 +127,22 @@ class WebMvcEndpointCorsIntegrationTests {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com",
"management.endpoints.web.cors.allowed-headers:Alpha,Bravo")
.run(withMockMvc((mockMvc) -> mockMvc
.perform(options("/actuator/beans").header("Origin", "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Alpha"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Alpha"))));
.run(withMockMvc((mvc) -> assertThat(mvc.options()
.uri("/actuator/beans")
.header("Origin", "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Alpha")).hasStatusOk()
.headers()
.hasValue(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "Alpha")));
}
@Test
void requestsWithDisallowedMethodsAreRejected() {
this.contextRunner.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com")
.run(withMockMvc((mockMvc) -> mockMvc
.perform(options("/actuator/beans").header(HttpHeaders.ORIGIN, "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "PATCH"))
.andExpect(status().isForbidden())));
.run(withMockMvc((mvc) -> assertThat(mvc.options()
.uri("/actuator/beans")
.header(HttpHeaders.ORIGIN, "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "PATCH")).hasStatus(HttpStatus.FORBIDDEN)));
}
@Test
@ -147,11 +150,12 @@ class WebMvcEndpointCorsIntegrationTests {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com",
"management.endpoints.web.cors.allowed-methods:GET,HEAD")
.run(withMockMvc((mockMvc) -> mockMvc
.perform(options("/actuator/beans").header(HttpHeaders.ORIGIN, "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "HEAD"))
.andExpect(status().isOk())
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD"))));
.run(withMockMvc((mvc) -> assertThat(mvc.options()
.uri("/actuator/beans")
.header(HttpHeaders.ORIGIN, "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "HEAD")).hasStatusOk()
.headers()
.hasValue(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,HEAD")));
}
@Test
@ -159,8 +163,10 @@ class WebMvcEndpointCorsIntegrationTests {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com",
"management.endpoints.web.cors.allow-credentials:true")
.run(withMockMvc((mockMvc) -> performAcceptedCorsRequest(mockMvc)
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"))));
.run(withMockMvc((mvc) -> {
MvcTestResult result = performAcceptedCorsRequest(mvc);
assertThat(result).hasHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
}));
}
@Test
@ -168,31 +174,28 @@ class WebMvcEndpointCorsIntegrationTests {
this.contextRunner
.withPropertyValues("management.endpoints.web.cors.allowed-origins:foo.example.com",
"management.endpoints.web.cors.allow-credentials:false")
.run(withMockMvc((mockMvc) -> performAcceptedCorsRequest(mockMvc)
.andExpect(header().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS))));
.run(withMockMvc((mvc) -> {
MvcTestResult result = performAcceptedCorsRequest(mvc);
assertThat(result).doesNotContainHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS);
}));
}
private ContextConsumer<WebApplicationContext> withMockMvc(MockMvcConsumer mockMvc) {
return (context) -> mockMvc.accept(MockMvcBuilders.webAppContextSetup(context).build());
private ContextConsumer<WebApplicationContext> withMockMvc(ThrowingConsumer<MockMvcTester> mvc) {
return (context) -> mvc.accept(MockMvcTester.from(context));
}
private ResultActions performAcceptedCorsRequest(MockMvc mockMvc) throws Exception {
return performAcceptedCorsRequest(mockMvc, "/actuator/beans");
private MvcTestResult performAcceptedCorsRequest(MockMvcTester mvc) {
return performAcceptedCorsRequest(mvc, "/actuator/beans");
}
private ResultActions performAcceptedCorsRequest(MockMvc mockMvc, String url) throws Exception {
return mockMvc
.perform(options(url).header(HttpHeaders.ORIGIN, "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"))
.andExpect(header().string(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "foo.example.com"))
.andExpect(status().isOk());
}
@FunctionalInterface
interface MockMvcConsumer {
void accept(MockMvc mockMvc) throws Exception;
private MvcTestResult performAcceptedCorsRequest(MockMvcTester mvc, String url) {
MvcTestResult result = mvc.options()
.uri(url)
.header(HttpHeaders.ORIGIN, "foo.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET")
.exchange();
assertThat(result).hasStatusOk().hasHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "foo.example.com");
return result;
}
}

View File

@ -47,24 +47,17 @@ import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebAp
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.test.context.TestSecurityContextHolder;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.web.util.pattern.PathPatternParser;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.hasKey;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests for the Actuator's MVC endpoints.
@ -92,25 +85,26 @@ class WebMvcEndpointIntegrationTests {
}
@Test
void endpointsAreSecureByDefault() throws Exception {
void endpointsAreSecureByDefault() {
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/actuator/beans").accept(MediaType.APPLICATION_JSON)).andExpect(status().isUnauthorized());
MockMvcTester mvc = createSecureMockMvcTester();
assertThat(mvc.get().uri("/actuator/beans").accept(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.UNAUTHORIZED);
}
@Test
void endpointsAreSecureByDefaultWithCustomBasePath() throws Exception {
void endpointsAreSecureByDefaultWithCustomBasePath() {
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(SecureConfiguration.class);
TestPropertyValues.of("management.endpoints.web.base-path:/management").applyTo(this.context);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/management/beans").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized());
MockMvcTester mvc = createSecureMockMvcTester();
assertThat(mvc.get().uri("/management/beans").accept(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.UNAUTHORIZED);
}
@Test
void endpointsAreSecureWithActuatorRoleWithCustomBasePath() throws Exception {
void endpointsAreSecureWithActuatorRoleWithCustomBasePath() {
TestSecurityContextHolder.getContext()
.setAuthentication(new TestingAuthenticationToken("user", "N/A", "ROLE_ACTUATOR"));
this.context = new AnnotationConfigServletWebApplicationContext();
@ -118,55 +112,54 @@ class WebMvcEndpointIntegrationTests {
TestPropertyValues
.of("management.endpoints.web.base-path:/management", "management.endpoints.web.exposure.include=*")
.applyTo(this.context);
MockMvc mockMvc = createSecureMockMvc();
mockMvc.perform(get("/management/beans")).andExpect(status().isOk());
MockMvcTester mvc = createSecureMockMvcTester();
assertThat(mvc.get().uri("/management/beans")).hasStatusOk();
}
@Test
void linksAreProvidedToAllEndpointTypes() throws Exception {
void linksAreProvidedToAllEndpointTypes() {
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class);
TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context);
MockMvc mockMvc = doCreateMockMvc();
mockMvc.perform(get("/actuator").accept("*/*"))
.andExpect(status().isOk())
.andExpect(jsonPath("_links",
both(hasKey("beans")).and(hasKey("servlet"))
.and(hasKey("restcontroller"))
.and(hasKey("controller"))));
MockMvcTester mvc = doCreateMockMvcTester();
assertThat(mvc.get().uri("/actuator").accept("*/*")).hasStatusOk()
.bodyJson()
.extractingPath("_links")
.asMap()
.containsKeys("beans", "servlet", "restcontroller", "controller");
}
@Test
void linksPageIsNotAvailableWhenDisabled() throws Exception {
void linksPageIsNotAvailableWhenDisabled() {
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(DefaultConfiguration.class, EndpointsConfiguration.class);
TestPropertyValues.of("management.endpoints.web.discovery.enabled=false").applyTo(this.context);
MockMvc mockMvc = doCreateMockMvc();
mockMvc.perform(get("/actuator").accept("*/*")).andExpect(status().isNotFound());
MockMvcTester mvc = doCreateMockMvcTester();
assertThat(mvc.get().uri("/actuator").accept("*/*")).hasStatus(HttpStatus.NOT_FOUND);
}
@Test
void endpointObjectMapperCanBeApplied() throws Exception {
void endpointObjectMapperCanBeApplied() {
this.context = new AnnotationConfigServletWebApplicationContext();
this.context.register(EndpointObjectMapperConfiguration.class, DefaultConfiguration.class);
TestPropertyValues.of("management.endpoints.web.exposure.include=*").applyTo(this.context);
MockMvc mockMvc = doCreateMockMvc();
MvcResult result = mockMvc.perform(get("/actuator/beans")).andExpect(status().isOk()).andReturn();
assertThat(result.getResponse().getContentAsString()).contains("\"scope\":\"notelgnis\"");
MockMvcTester mvc = doCreateMockMvcTester();
assertThat(mvc.get().uri("/actuator/beans")).hasStatusOk().bodyText().contains("\"scope\":\"notelgnis\"");
}
private MockMvc createSecureMockMvc() {
return doCreateMockMvc(springSecurity());
private MockMvcTester createSecureMockMvcTester() {
return doCreateMockMvcTester(springSecurity());
}
private MockMvc doCreateMockMvc(MockMvcConfigurer... configurers) {
private MockMvcTester doCreateMockMvcTester(MockMvcConfigurer... configurers) {
this.context.setServletContext(new MockServletContext());
this.context.refresh();
DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(this.context);
for (MockMvcConfigurer configurer : configurers) {
builder.apply(configurer);
}
return builder.build();
return MockMvcTester.from(this.context, (builder) -> {
for (MockMvcConfigurer configurer : configurers) {
builder.apply(configurer);
}
return builder.build();
});
}
@ImportAutoConfiguration({ JacksonAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -40,14 +40,11 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.server.observation.DefaultServerRequestObservationConvention;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.filter.ServerHttpObservationFilter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcObservationAutoConfiguration}.
@ -173,14 +170,13 @@ class WebMvcObservationAutoConfigurationTests {
return getInitializedMeterRegistry(context, "/test0", "/test1", "/test2");
}
private MeterRegistry getInitializedMeterRegistry(AssertableWebApplicationContext context, String... urls)
throws Exception {
private MeterRegistry getInitializedMeterRegistry(AssertableWebApplicationContext context, String... urls) {
assertThat(context).hasSingleBean(FilterRegistrationBean.class);
Filter filter = context.getBean(FilterRegistrationBean.class).getFilter();
assertThat(filter).isInstanceOf(ServerHttpObservationFilter.class);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).addFilters(filter).build();
MockMvcTester mvc = MockMvcTester.from(context, (builder) -> builder.addFilters(filter).build());
for (String url : urls) {
mockMvc.perform(MockMvcRequestBuilders.get(url)).andExpect(status().isOk());
assertThat(mvc.get().uri(url)).hasStatusOk();
}
return context.getBean(MeterRegistry.class);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2024 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.boot.autoconfigure.graphql.security;
import graphql.schema.idl.TypeRuntimeWiring;
import org.assertj.core.api.ThrowingConsumer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -46,17 +47,13 @@ import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link GraphQlWebMvcSecurityAutoConfiguration}.
@ -81,46 +78,46 @@ class GraphQlWebMvcSecurityAutoConfigurationTests {
@Test
void anonymousUserShouldBeUnauthorized() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author }}";
mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("data.bookById.name").doesNotExist())
.andExpect(jsonPath("errors[0].extensions.classification").value(ErrorType.UNAUTHORIZED.toString()));
assertThat(mvc.post().uri("/graphql").content("{\"query\": \"" + query + "\"}")).satisfies((result) -> {
assertThat(result).hasStatusOk().hasContentTypeCompatibleWith(MediaType.APPLICATION_JSON);
assertThat(result).bodyJson()
.doesNotHavePath("data.bookById.name")
.extractingPath("errors[0].extensions.classification")
.asString()
.isEqualTo(ErrorType.UNAUTHORIZED.toString());
});
});
}
@Test
void authenticatedUserShouldGetData() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author }}";
mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}").with(user("rob")))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("data.bookById.name").value("GraphQL for beginners"))
.andExpect(jsonPath("errors").doesNotExist());
assertThat(mvc.post().uri("/graphql").content("{\"query\": \"" + query + "\"}").with(user("rob")))
.satisfies((result) -> {
assertThat(result).hasStatusOk().hasContentTypeCompatibleWith(MediaType.APPLICATION_JSON);
assertThat(result).bodyJson()
.doesNotHavePath("errors")
.extractingPath("data.bookById.name")
.asString()
.isEqualTo("GraphQL for beginners");
});
});
}
private void testWith(MockMvcConsumer mockMvcConsumer) {
private void withMockMvc(ThrowingConsumer<MockMvcTester> mvc) {
this.contextRunner.run((context) -> {
MediaType mediaType = MediaType.APPLICATION_JSON;
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context)
.defaultRequest(post("/graphql").contentType(mediaType).accept(mediaType))
.apply(springSecurity())
.build();
mockMvcConsumer.accept(mockMvc);
MockMvcTester mockMVc = MockMvcTester.from(context,
(builder) -> builder.defaultRequest(post("/graphql").contentType(mediaType).accept(mediaType))
.apply(springSecurity())
.build());
mvc.accept(mockMVc);
});
}
private interface MockMvcConsumer {
void accept(MockMvc mockMvc) throws Exception;
}
@Configuration(proxyBeanMethods = false)
static class DataFetchersConfiguration {

View File

@ -17,10 +17,11 @@
package org.springframework.boot.autoconfigure.graphql.servlet;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import graphql.schema.idl.TypeRuntimeWiring;
import org.hamcrest.Matchers;
import org.assertj.core.api.ThrowingConsumer;
import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
@ -42,9 +43,9 @@ import org.springframework.graphql.server.WebGraphQlInterceptor;
import org.springframework.graphql.server.webmvc.GraphQlHttpHandler;
import org.springframework.graphql.server.webmvc.GraphQlWebSocketHandler;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.support.RouterFunctionMapping;
@ -52,13 +53,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
import org.springframework.web.socket.server.support.WebSocketHandlerMapping;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link GraphQlWebMvcAutoConfiguration}.
@ -85,93 +80,100 @@ class GraphQlWebMvcAutoConfigurationTests {
@Test
void simpleQueryShouldWork() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }";
mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_GRAPHQL_RESPONSE))
.andExpect(jsonPath("data.bookById.name").value("GraphQL for beginners"));
assertThat(mvc.post().uri("/graphql").content("{\"query\": \"" + query + "\"}")).satisfies((result) -> {
assertThat(result).hasStatusOk().hasContentTypeCompatibleWith(MediaType.APPLICATION_GRAPHQL_RESPONSE);
assertThat(result).bodyJson()
.extractingPath("data.bookById.name")
.asString()
.isEqualTo("GraphQL for beginners");
});
});
}
@Test
void SseSubscriptionShouldWork() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{ booksOnSale(minPages: 50){ id name pageCount author } }";
mockMvc
.perform(post("/graphql").accept(MediaType.TEXT_EVENT_STREAM)
.content("{\"query\": \"subscription TestSubscription " + query + "\"}"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_EVENT_STREAM))
.andExpect(content().string(Matchers.stringContainsInOrder("event:next",
"data:{\"data\":{\"booksOnSale\":{\"id\":\"book-1\",\"name\":\"GraphQL for beginners\",\"pageCount\":100,\"author\":\"John GraphQL\"}}}",
"event:next",
"data:{\"data\":{\"booksOnSale\":{\"id\":\"book-2\",\"name\":\"Harry Potter and the Philosopher's Stone\",\"pageCount\":223,\"author\":\"Joanne Rowling\"}}}")));
assertThat(mvc.post()
.uri("/graphql")
.accept(MediaType.TEXT_EVENT_STREAM)
.content("{\"query\": \"subscription TestSubscription " + query + "\"}")).satisfies((result) -> {
assertThat(result).hasStatusOk().hasContentTypeCompatibleWith(MediaType.TEXT_EVENT_STREAM);
assertThat(result).bodyText()
.containsSubsequence("event:next",
"data:{\"data\":{\"booksOnSale\":{\"id\":\"book-1\",\"name\":\"GraphQL for beginners\",\"pageCount\":100,\"author\":\"John GraphQL\"}}}",
"event:next",
"data:{\"data\":{\"booksOnSale\":{\"id\":\"book-2\",\"name\":\"Harry Potter and the Philosopher's Stone\",\"pageCount\":223,\"author\":\"Joanne Rowling\"}}}");
});
});
}
@Test
void httpGetQueryShouldBeSupported() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }";
mockMvc.perform(get("/graphql?query={query}", "{\"query\": \"" + query + "\"}"))
.andExpect(status().isMethodNotAllowed())
.andExpect(header().string("Allow", "POST"));
assertThat(mvc.get().uri("/graphql?query={query}", "{\"query\": \"" + query + "\"}"))
.hasStatus(HttpStatus.METHOD_NOT_ALLOWED)
.headers()
.hasValue("Allow", "POST");
});
}
@Test
void shouldRejectMissingQuery() {
testWith((mockMvc) -> mockMvc.perform(post("/graphql").content("{}")).andExpect(status().isBadRequest()));
withMockMvc((mvc) -> assertThat(mvc.post().uri("/graphql").content("{}")).hasStatus(HttpStatus.BAD_REQUEST));
}
@Test
void shouldRejectQueryWithInvalidJson() {
testWith((mockMvc) -> mockMvc.perform(post("/graphql").content(":)")).andExpect(status().isBadRequest()));
withMockMvc((mvc) -> assertThat(mvc.post().uri("/graphql").content(":)")).hasStatus(HttpStatus.BAD_REQUEST));
}
@Test
void shouldConfigureWebInterceptors() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{ bookById(id: \\\"book-1\\\"){ id name pageCount author } }";
mockMvc.perform(post("/graphql").content("{\"query\": \"" + query + "\"}"))
.andExpect(status().isOk())
.andExpect(header().string("X-Custom-Header", "42"));
assertThat(mvc.post().uri("/graphql").content("{\"query\": \"" + query + "\"}")).hasStatusOk()
.headers()
.hasValue("X-Custom-Header", "42");
});
}
@Test
void shouldExposeSchemaEndpoint() {
testWith((mockMvc) -> mockMvc.perform(get("/graphql/schema"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.TEXT_PLAIN))
.andExpect(content().string(Matchers.containsString("type Book"))));
withMockMvc((mvc) -> assertThat(mvc.get().uri("/graphql/schema")).hasStatusOk()
.hasContentType(MediaType.TEXT_PLAIN)
.bodyText()
.contains("type Book"));
}
@Test
void shouldExposeGraphiqlEndpoint() {
testWith((mockMvc) -> {
mockMvc.perform(get("/graphiql"))
.andExpect(status().is3xxRedirection())
.andExpect(redirectedUrl("http://localhost/graphiql?path=/graphql"));
mockMvc.perform(get("/graphiql?path=/graphql"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.TEXT_HTML));
withMockMvc((mvc) -> {
assertThat(mvc.get().uri("/graphiql")).hasStatus3xxRedirection()
.hasRedirectedUrl("http://localhost/graphiql?path=/graphql");
assertThat(mvc.get().uri("/graphiql?path=/graphql")).hasStatusOk()
.contentType()
.isEqualTo(MediaType.TEXT_HTML);
});
}
@Test
void shouldSupportCors() {
testWith((mockMvc) -> {
withMockMvc((mvc) -> {
String query = "{" + " bookById(id: \\\"book-1\\\"){ " + " id" + " name" + " pageCount"
+ " author" + " }" + "}";
mockMvc
.perform(post("/graphql").header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(HttpHeaders.ORIGIN, "https://example.com")
.content("{\"query\": \"" + query + "\"}"))
.andExpect(status().isOk())
.andExpect(header().stringValues(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "https://example.com"))
.andExpect(header().stringValues(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"));
assertThat(mvc.post()
.uri("/graphql")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(HttpHeaders.ORIGIN, "https://example.com")
.content("{\"query\": \"" + query + "\"}"))
.satisfies((result) -> assertThat(result).hasStatusOk()
.headers()
.containsEntry(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, List.of("https://example.com"))
.containsEntry(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, List.of("true")));
});
}
@ -217,22 +219,17 @@ class GraphQlWebMvcAutoConfigurationTests {
assertThat(RuntimeHintsPredicates.resource().forResource("graphiql/index.html")).accepts(hints);
}
private void testWith(MockMvcConsumer mockMvcConsumer) {
private void withMockMvc(ThrowingConsumer<MockMvcTester> mvc) {
this.contextRunner.run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context)
.defaultRequest(post("/graphql").contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_GRAPHQL_RESPONSE))
.build();
mockMvcConsumer.accept(mockMvc);
MockMvcTester mockMVc = MockMvcTester.from(context,
(builder) -> builder
.defaultRequest(post("/graphql").contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_GRAPHQL_RESPONSE))
.build());
mvc.accept(mockMVc);
});
}
private interface MockMvcConsumer {
void accept(MockMvc mockMvc) throws Exception;
}
@Configuration(proxyBeanMethods = false)
static class DataFetchersConfiguration {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.assertj.core.api.ThrowingConsumer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -30,6 +31,8 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
@ -39,18 +42,14 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.AbstractView;
import org.springframework.web.servlet.view.InternalResourceView;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WelcomePageHandlerMapping}.
@ -76,50 +75,35 @@ class WelcomePageHandlerMappingTests {
@Test
void handlesRequestForStaticPageThatAcceptsTextHtml() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(forwardedUrl("index.html")));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.TEXT_HTML)).hasStatusOk()
.hasForwardedUrl("index.html")));
}
@Test
void handlesRequestForStaticPageThatAcceptsAll() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.ALL))
.andExpect(status().isOk())
.andExpect(forwardedUrl("index.html")));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.ALL)).hasStatusOk()
.hasForwardedUrl("index.html")));
}
@Test
void doesNotHandleRequestThatDoesNotAcceptTextHtml() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound()));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.NOT_FOUND)));
}
@Test
void handlesRequestWithNoAcceptHeader() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("index.html")));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/")).hasStatusOk().hasForwardedUrl("index.html")));
}
@Test
void handlesRequestWithEmptyAcceptHeader() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").header(HttpHeaders.ACCEPT, ""))
.andExpect(status().isOk())
.andExpect(forwardedUrl("index.html")));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").header(HttpHeaders.ACCEPT, "")).hasStatusOk()
.hasForwardedUrl("index.html")));
}
@Test
@ -131,54 +115,43 @@ class WelcomePageHandlerMappingTests {
@Test
void producesNotFoundResponseWhenThereIsNoWelcomePage() {
this.contextRunner.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.TEXT_HTML))
.andExpect(status().isNotFound()));
this.contextRunner.run(testWith(
(mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.TEXT_HTML)).hasStatus(HttpStatus.NOT_FOUND)));
}
@Test
void handlesRequestForTemplateThatAcceptsTextHtml() {
this.contextRunner.withUserConfiguration(TemplateConfiguration.class).run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/").accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string("index template"));
});
this.contextRunner.withUserConfiguration(TemplateConfiguration.class)
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.TEXT_HTML)).hasStatusOk()
.hasBodyTextEqualTo("index template")));
}
@Test
void handlesRequestForTemplateThatAcceptsAll() {
this.contextRunner.withUserConfiguration(TemplateConfiguration.class).run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/").accept(MediaType.ALL))
.andExpect(status().isOk())
.andExpect(content().string("index template"));
});
this.contextRunner.withUserConfiguration(TemplateConfiguration.class)
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.ALL)).hasStatusOk()
.hasBodyTextEqualTo("index template")));
}
@Test
void prefersAStaticResourceToATemplate() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class, TemplateConfiguration.class)
.run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/").accept(MediaType.ALL))
.andExpect(status().isOk())
.andExpect(forwardedUrl("index.html"));
});
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.ALL)).hasStatusOk()
.hasForwardedUrl("index.html")));
}
@Test
void logsInvalidAcceptHeader(CapturedOutput output) {
this.contextRunner.withUserConfiguration(TemplateConfiguration.class).run((context) -> {
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
mockMvc.perform(get("/").accept("*/*q=0.8"))
.andExpect(status().isOk())
.andExpect(content().string("index template"));
});
this.contextRunner.withUserConfiguration(TemplateConfiguration.class)
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept("*/*q=0.8")).hasStatusOk()
.hasBodyTextEqualTo("index template")));
assertThat(output).contains("Received invalid Accept header. Assuming all media types are accepted");
}
private ContextConsumer<AssertableWebApplicationContext> testWith(ThrowingConsumer<MockMvcTester> mvc) {
return (context) -> mvc.accept(MockMvcTester.from(context));
}
@Configuration(proxyBeanMethods = false)
static class HandlerMappingConfiguration {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package org.springframework.boot.autoconfigure.web.servlet;
import org.assertj.core.api.ThrowingConsumer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.ObjectProvider;
@ -23,6 +24,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.template.TemplateAvailabilityProviders;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@ -31,14 +34,13 @@ import org.springframework.core.Ordered;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WelcomePageNotAcceptableHandlerMapping}.
@ -66,37 +68,28 @@ class WelcomePageNotAcceptableHandlerMappingTests {
@Test
void handlesRequestForStaticPageThatAcceptsTextHtml() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.TEXT_HTML))
.andExpect(status().isNotAcceptable()));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.TEXT_HTML))
.hasStatus(HttpStatus.NOT_ACCEPTABLE)));
}
@Test
void handlesRequestForStaticPagetThatDoesNotAcceptTextHtml() {
void handlesRequestForStaticPageThatDoesNotAcceptTextHtml() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isNotAcceptable()));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.APPLICATION_JSON))
.hasStatus(HttpStatus.NOT_ACCEPTABLE)));
}
@Test
void handlesRequestWithNoAcceptHeader() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/"))
.andExpect(status().isNotAcceptable()));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/")).hasStatus(HttpStatus.NOT_ACCEPTABLE)));
}
@Test
void handlesRequestWithEmptyAcceptHeader() {
this.contextRunner.withUserConfiguration(StaticResourceConfiguration.class)
.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").header(HttpHeaders.ACCEPT, ""))
.andExpect(status().isNotAcceptable()));
.run(testWith((mvc) -> assertThat(mvc.get().uri("/").header(HttpHeaders.ACCEPT, ""))
.hasStatus(HttpStatus.NOT_ACCEPTABLE)));
}
@Test
@ -109,10 +102,12 @@ class WelcomePageNotAcceptableHandlerMappingTests {
@Test
void producesNotFoundResponseWhenThereIsNoWelcomePage() {
this.contextRunner.run((context) -> MockMvcBuilders.webAppContextSetup(context)
.build()
.perform(get("/").accept(MediaType.TEXT_HTML))
.andExpect(status().isNotFound()));
this.contextRunner.run(testWith(
(mvc) -> assertThat(mvc.get().uri("/").accept(MediaType.TEXT_HTML)).hasStatus(HttpStatus.NOT_FOUND)));
}
private ContextConsumer<AssertableWebApplicationContext> testWith(ThrowingConsumer<MockMvcTester> mvc) {
return (context) -> mvc.accept(MockMvcTester.from(context));
}
@Configuration(proxyBeanMethods = false)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,19 +42,14 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link BasicErrorController} using {@link MockMvc} but not
* Tests for {@link BasicErrorController} using {@link MockMvcTester} but not
* {@link org.springframework.test.context.junit.jupiter.SpringExtension}.
*
* @author Dave Syer
@ -64,7 +59,7 @@ class BasicErrorControllerDirectMockMvcTests {
private ConfigurableWebApplicationContext wac;
private MockMvc mockMvc;
private MockMvcTester mvc;
@AfterEach
void close() {
@ -73,49 +68,44 @@ class BasicErrorControllerDirectMockMvcTests {
void setup(ConfigurableWebApplicationContext context) {
this.wac = context;
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.mvc = MockMvcTester.from(this.wac);
}
@Test
void errorPageAvailableWithParentContext() throws Exception {
void errorPageAvailableWithParentContext() {
setup((ConfigurableWebApplicationContext) new SpringApplicationBuilder(ParentConfiguration.class)
.child(ChildConfiguration.class)
.run("--server.port=0"));
MvcResult response = this.mockMvc.perform(get("/error").accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("status=999");
assertThat(this.mvc.get().uri("/error").accept(MediaType.TEXT_HTML)).hasStatus5xxServerError()
.bodyText()
.contains("status=999");
}
@Test
void errorPageAvailableWithMvcIncluded() throws Exception {
void errorPageAvailableWithMvcIncluded() {
setup((ConfigurableWebApplicationContext) new SpringApplication(WebMvcIncludedConfiguration.class)
.run("--server.port=0"));
MvcResult response = this.mockMvc.perform(get("/error").accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("status=999");
assertThat(this.mvc.get().uri("/error").accept(MediaType.TEXT_HTML)).hasStatus5xxServerError()
.bodyText()
.contains("status=999");
}
@Test
void errorPageNotAvailableWithWhitelabelDisabled() {
setup((ConfigurableWebApplicationContext) new SpringApplication(WebMvcIncludedConfiguration.class)
.run("--server.port=0", "--server.error.whitelabel.enabled=false"));
assertThatExceptionOfType(ServletException.class)
.isThrownBy(() -> this.mockMvc.perform(get("/error").accept(MediaType.TEXT_HTML)));
assertThat(this.mvc.get().uri("/error").accept(MediaType.TEXT_HTML)).hasFailed()
.failure()
.isInstanceOf(ServletException.class);
}
@Test
void errorControllerWithAop() throws Exception {
void errorControllerWithAop() {
setup((ConfigurableWebApplicationContext) new SpringApplication(WithAopConfiguration.class)
.run("--server.port=0"));
MvcResult response = this.mockMvc.perform(get("/error").accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("status=999");
assertThat(this.mvc.get().uri("/error").accept(MediaType.TEXT_HTML)).hasStatus5xxServerError()
.bodyText()
.contains("status=999");
}
@Target(ElementType.TYPE)

View File

@ -47,10 +47,10 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.test.web.servlet.assertj.MvcTestResult;
import org.springframework.util.ReflectionUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
@ -63,11 +63,9 @@ import org.springframework.web.servlet.View;
import org.springframework.web.servlet.view.AbstractView;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link BasicErrorController} using {@link MockMvc} and
* Tests for {@link BasicErrorController} using {@link MockMvcTester} and
* {@link SpringBootTest @SpringBootTest}.
*
* @author Dave Syer
@ -80,60 +78,51 @@ class BasicErrorControllerMockMvcTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
private MockMvcTester mvc;
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.mvc = MockMvcTester.from(this.wac);
}
@Test
void testDirectAccessForMachineClient() throws Exception {
MvcResult response = this.mockMvc.perform(get("/error")).andExpect(status().is5xxServerError()).andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("999");
void testDirectAccessForMachineClient() {
assertThat(this.mvc.get().uri("/error")).hasStatus5xxServerError().bodyText().contains("999");
}
@Test
void testErrorWithNotFoundResponseStatus() throws Exception {
MvcResult result = this.mockMvc.perform(get("/bang")).andExpect(status().isNotFound()).andReturn();
MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error")).andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("Expected!");
void testErrorWithNotFoundResponseStatus() {
assertThat(this.mvc.get().uri("/bang")).hasStatus(HttpStatus.NOT_FOUND)
.satisfies((result) -> assertThat(this.mvc.perform(new ErrorDispatcher(result, "/error"))).bodyText()
.contains("Expected!"));
}
@Test
void testErrorWithNoContentResponseStatus() throws Exception {
MvcResult result = this.mockMvc.perform(get("/noContent").accept("some/thing"))
.andExpect(status().isNoContent())
.andReturn();
MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error"))
.andExpect(status().isNoContent())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).isEmpty();
void testErrorWithNoContentResponseStatus() {
assertThat(this.mvc.get().uri("/noContent").accept("some/thing")).hasStatus(HttpStatus.NO_CONTENT)
.satisfies((result) -> assertThat(this.mvc.perform(new ErrorDispatcher(result, "/error")))
.hasStatus(HttpStatus.NO_CONTENT)
.body()
.isEmpty());
}
@Test
void testBindingExceptionForMachineClient() throws Exception {
void testBindingExceptionForMachineClient() {
// In a real server the response is carried over into the error dispatcher, but
// in the mock a new one is created so we have to assert the status at this
// intermediate point
MvcResult result = this.mockMvc.perform(get("/bind")).andExpect(status().is4xxClientError()).andReturn();
MvcResult response = this.mockMvc.perform(new ErrorDispatcher(result, "/error")).andReturn();
// And the rendered status code is always wrong (but would be 400 in a real
// system)
String content = response.getResponse().getContentAsString();
assertThat(content).contains("Validation failed");
// in the mock a new one is created, so we have to assert the status at this
// intermediate point, and the rendered status code is always wrong (but would
// be 400 in a real system)
assertThat(this.mvc.get().uri("/bind")).hasStatus4xxClientError()
.satisfies((result) -> assertThat(this.mvc.perform(new ErrorDispatcher(result, "/error"))).bodyText()
.contains("Validation failed"));
}
@Test
void testDirectAccessForBrowserClient() throws Exception {
MvcResult response = this.mockMvc.perform(get("/error").accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("ERROR_BEAN");
void testDirectAccessForBrowserClient() {
assertThat(this.mvc.get().uri("/error").accept(MediaType.TEXT_HTML)).hasStatus5xxServerError()
.bodyText()
.contains("ERROR_BEAN");
}
@Target(ElementType.TYPE)
@ -225,8 +214,8 @@ class BasicErrorControllerMockMvcTests {
private final String path;
ErrorDispatcher(MvcResult result, String path) {
this.result = result;
ErrorDispatcher(MvcTestResult mvcTestResult, String path) {
this.result = mvcTestResult.getMvcResult();
this.path = path;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,14 +37,10 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.context.WebApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests for the default error view.
@ -59,49 +55,38 @@ class DefaultErrorViewIntegrationTests {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
private MockMvcTester mvc;
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.mvc = MockMvcTester.from(this.wac);
}
@Test
void testErrorForBrowserClient() throws Exception {
MvcResult response = this.mockMvc.perform(get("/error").accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("<html>");
assertThat(content).contains("999");
void testErrorForBrowserClient() {
assertThat(this.mvc.get().uri("/error").accept(MediaType.TEXT_HTML)).hasStatus5xxServerError()
.bodyText()
.contains("<html>", "999");
}
@Test
void testErrorWithHtmlEscape() throws Exception {
MvcResult response = this.mockMvc
.perform(
get("/error")
.requestAttr("jakarta.servlet.error.exception",
new RuntimeException("<script>alert('Hello World')</script>"))
.accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).contains("&lt;script&gt;");
assertThat(content).contains("Hello World");
assertThat(content).contains("999");
void testErrorWithHtmlEscape() {
assertThat(this.mvc.get()
.uri("/error")
.requestAttr("jakarta.servlet.error.exception",
new RuntimeException("<script>alert('Hello World')</script>"))
.accept(MediaType.TEXT_HTML)).hasStatus5xxServerError()
.bodyText()
.contains("&lt;script&gt;", "Hello World", "999");
}
@Test
void testErrorWithSpelEscape() throws Exception {
void testErrorWithSpelEscape() {
String spel = "${T(" + getClass().getName() + ").injectCall()}";
MvcResult response = this.mockMvc
.perform(get("/error").requestAttr("jakarta.servlet.error.exception", new RuntimeException(spel))
.accept(MediaType.TEXT_HTML))
.andExpect(status().is5xxServerError())
.andReturn();
String content = response.getResponse().getContentAsString();
assertThat(content).doesNotContain("injection");
assertThat(this.mvc.get()
.uri("/error")
.requestAttr("jakarta.servlet.error.exception", new RuntimeException(spel))
.accept(MediaType.TEXT_HTML)).hasStatus5xxServerError().bodyText().doesNotContain("injection");
}
static String injectCall() {

View File

@ -36,6 +36,7 @@ import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.mock.web.MockFilterChain;
@ -43,15 +44,12 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.config.BeanIds;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link RemoteDevToolsAutoConfiguration}.
@ -150,14 +148,10 @@ class RemoteDevToolsAutoConfigurationTests {
void securityConfigurationShouldAllowAccess() throws Exception {
this.context = getContext(() -> loadContext("spring.devtools.remote.secret:supersecret"));
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(springSecurity())
.addFilter(filter)
.build();
mockMvc
.perform(MockMvcRequestBuilders.get(DEFAULT_CONTEXT_PATH + "/restart")
.header(DEFAULT_SECRET_HEADER_NAME, "supersecret"))
.andExpect(status().isOk());
MockMvcTester mvc = MockMvcTester.from(this.context,
(builder) -> builder.apply(springSecurity()).addFilter(filter).build());
assertThat(mvc.get().uri(DEFAULT_CONTEXT_PATH + "/restart").header(DEFAULT_SECRET_HEADER_NAME, "supersecret"))
.hasStatusOk();
assertRestartInvoked(true);
assertThat(this.context.containsBean("devtoolsSecurityFilterChain")).isTrue();
}
@ -167,14 +161,10 @@ class RemoteDevToolsAutoConfigurationTests {
this.context = getContext(() -> loadContext("spring.devtools.remote.secret:supersecret",
"server.servlet.context-path:/test", "spring.devtools.remote.context-path:/custom"));
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(springSecurity())
.addFilter(filter)
.build();
mockMvc
.perform(MockMvcRequestBuilders.get("/test/custom/restart")
.header(DEFAULT_SECRET_HEADER_NAME, "supersecret"))
.andExpect(status().isOk());
MockMvcTester mvc = MockMvcTester.from(this.context,
(builder) -> builder.apply(springSecurity()).addFilter(filter).build());
assertThat(mvc.get().uri("/test/custom/restart").header(DEFAULT_SECRET_HEADER_NAME, "supersecret"))
.hasStatusOk();
assertRestartInvoked(true);
}
@ -183,11 +173,9 @@ class RemoteDevToolsAutoConfigurationTests {
this.context = getContext(() -> loadContext("spring.devtools.remote.secret:supersecret"));
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
Filter securityFilterChain = this.context.getBean(BeanIds.SPRING_SECURITY_FILTER_CHAIN, Filter.class);
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.addFilter(securityFilterChain)
.addFilter(filter)
.build();
mockMvc.perform(MockMvcRequestBuilders.get("/my-path")).andExpect(status().isUnauthorized());
MockMvcTester mvc = MockMvcTester.from(this.context,
(builder) -> builder.addFilter(securityFilterChain).addFilter(filter).build());
assertThat(mvc.get().uri("/my-path")).hasStatus(HttpStatus.UNAUTHORIZED);
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,20 +21,20 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.assertj.core.api.Assertions.assertThat;
@WebMvcTest(UserController.class)
class MySecurityTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
@WithMockUser(roles = "ADMIN")
void requestProtectedUrlWithUser() throws Exception {
this.mvc.perform(get("/"));
void requestProtectedUrlWithUser() {
assertThat(this.mvc.get().uri("/")).doesNotHaveFailed();
}
}

View File

@ -22,24 +22,22 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs
class MyUserDocumentationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void listUsers() throws Exception {
this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andDo(document("list-users"));
void listUsers() {
assertThat(this.mvc.get().uri("/users").accept(MediaType.TEXT_PLAIN)).hasStatusOk()
.apply(document("list-users"));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,25 +16,23 @@
package org.springframework.boot.docs.features.testing.springbootapplications.autoconfiguredspringrestdocs.withmockmvc
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.http.MediaType
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.assertj.MockMvcTester
@WebMvcTest(UserController::class)
@AutoConfigureRestDocs
class MyUserDocumentationTests(@Autowired val mvc: MockMvc) {
class MyUserDocumentationTests(@Autowired val mvc: MockMvcTester) {
@Test
fun listUsers() {
mvc.perform(MockMvcRequestBuilders.get("/users").accept(MediaType.TEXT_PLAIN))
.andExpect(MockMvcResultMatchers.status().isOk)
.andDo(MockMvcRestDocumentation.document("list-users"))
assertThat(mvc.get().uri("/users").accept(MediaType.TEXT_PLAIN))
.hasStatusOk().apply(MockMvcRestDocumentation.document("list-users"))
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,18 +16,17 @@
package org.springframework.boot.docs.features.testing.springbootapplications.springmvctests
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito.given
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.assertj.MockMvcTester
@WebMvcTest(UserVehicleController::class)
class MyControllerTests(@Autowired val mvc: MockMvc) {
class MyControllerTests(@Autowired val mvc: MockMvcTester) {
@MockBean
lateinit var userVehicleService: UserVehicleService
@ -35,10 +34,9 @@ class MyControllerTests(@Autowired val mvc: MockMvc) {
@Test
fun testExample() {
given(userVehicleService.getVehicleDetails("sboot"))
.willReturn(VehicleDetails("Honda", "Civic"))
mvc.perform(MockMvcRequestBuilders.get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.content().string("Honda Civic"))
.willReturn(VehicleDetails("Honda", "Civic"))
assertThat(mvc.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.hasStatusOk().hasBodyTextEqualTo("Honda Civic")
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,24 +16,23 @@
package org.springframework.boot.docs.features.testing.springbootapplications.withmockenvironment
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.test.web.reactive.server.expectBody
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.assertj.MockMvcTester
@SpringBootTest
@AutoConfigureMockMvc
class MyMockMvcTests {
@Test
fun testWithMockMvc(@Autowired mvc: MockMvc) {
mvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.content().string("Hello World"))
fun testWithMockMvc(@Autowired mvc: MockMvcTester) {
assertThat(mvc.get().uri("/")).hasStatusOk()
.hasBodyTextEqualTo("Hello World")
}
// If Spring WebFlux is on the classpath, you can drive MVC tests with a WebTestClient
@ -41,10 +40,10 @@ class MyMockMvcTests {
@Test
fun testWithWebTestClient(@Autowired webClient: WebTestClient) {
webClient
.get().uri("/")
.exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Hello World")
.get().uri("/")
.exchange()
.expectStatus().isOk
.expectBody<String>().isEqualTo("Hello World")
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,20 +16,21 @@
package org.springframework.boot.docs.howto.testing.withspringsecurity
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.security.test.context.support.WithMockUser
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.assertj.MockMvcTester
@WebMvcTest(UserController::class)
class MySecurityTests(@Autowired val mvc: MockMvc) {
class MySecurityTests(@Autowired val mvc: MockMvcTester) {
@Test
@WithMockUser(roles = ["ADMIN"])
fun requestProtectedUrlWithUser() {
mvc.perform(MockMvcRequestBuilders.get("/"))
assertThat(mvc.get().uri("/"))
.doesNotHaveFailed()
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,7 +30,7 @@ import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
import org.springframework.restdocs.templates.TemplateFormats;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
@ -39,7 +39,6 @@ import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.li
import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
* Integration tests for advanced configuration of
@ -54,7 +53,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
class MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Autowired
private RestDocumentationResultHandler documentationHandler;
@ -68,10 +67,9 @@ class MockMvcRestDocsAutoConfigurationAdvancedConfigurationIntegrationTests {
}
@Test
void snippetGeneration() throws Exception {
this.mvc.perform(get("/"))
.andDo(this.documentationHandler
.document(links(linkWithRel("self").description("Canonical location of this resource"))));
void snippetGeneration() {
assertThat(this.mvc.get().uri("/")).apply(this.documentationHandler
.document(links(linkWithRel("self").description("Canonical location of this resource"))));
File defaultSnippetsDir = new File(this.generatedSnippets, "snippet-generation");
assertThat(defaultSnippetsDir).exists();
assertThat(contentOf(new File(defaultSnippetsDir, "curl-request.md"))).contains("'http://localhost:8080/'");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,13 +24,12 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.testsupport.BuildOutput;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.contentOf;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
/**
* Integration tests for {@link RestDocsAutoConfiguration} with Mock MVC.
@ -42,7 +41,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
class MockMvcRestDocsAutoConfigurationIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
private File generatedSnippets;
@ -53,8 +52,8 @@ class MockMvcRestDocsAutoConfigurationIntegrationTests {
}
@Test
void defaultSnippetsAreWritten() throws Exception {
this.mvc.perform(get("/")).andDo(document("default-snippets"));
void defaultSnippetsAreWritten() {
assertThat(this.mvc.get().uri("/")).apply(document("default-snippets"));
File defaultSnippetsDir = new File(this.generatedSnippets, "default-snippets");
assertThat(defaultSnippetsDir).exists();
assertThat(contentOf(new File(defaultSnippetsDir, "curl-request.adoc"))).contains("'https://api.example.com/'");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,13 +23,13 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for MockMvc security.
@ -41,25 +41,25 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class MockMvcSecurityIntegrationTests {
@Autowired
private MockMvc mockMvc;
private MockMvcTester mvc;
@Test
@WithMockUser(username = "test", password = "test", roles = "USER")
void okResponseWithMockUser() throws Exception {
this.mockMvc.perform(get("/")).andExpect(status().isOk());
void okResponseWithMockUser() {
assertThat(this.mvc.get().uri("/")).hasStatusOk();
}
@Test
void unauthorizedResponseWithNoUser() throws Exception {
this.mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andExpect(status().isUnauthorized());
void unauthorizedResponseWithNoUser() {
assertThat(this.mvc.get().uri("/").accept(MediaType.APPLICATION_JSON)).hasStatus(HttpStatus.UNAUTHORIZED);
}
@Test
void okResponseWithBasicAuthCredentialsForKnownUser() throws Exception {
this.mockMvc
.perform(get("/").header(HttpHeaders.AUTHORIZATION,
"Basic " + Base64.getEncoder().encodeToString("user:secret".getBytes())))
.andExpect(status().isOk());
void okResponseWithBasicAuthCredentialsForKnownUser() {
assertThat(this.mvc.get()
.uri("/")
.header(HttpHeaders.AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString("user:secret".getBytes())))
.hasStatusOk();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,11 +23,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.annotation.Import;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link AutoConfigureMockMvc @AutoConfigureMockMvc} and the ordering of Spring
@ -41,11 +39,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class AutoConfigureMockMvcSecurityFilterOrderingIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void afterSecurityFilterShouldFindAUserPrincipal() throws Exception {
this.mvc.perform(get("/one")).andExpect(status().isOk()).andExpect(content().string("user"));
void afterSecurityFilterShouldFindAUserPrincipal() {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("user");
}
}

View File

@ -39,6 +39,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
/**
* Tests for {@link SpringBootTest @SpringBootTest} with
* {@link AutoConfigureMockMvc @AutoConfigureMockMvc} (i.e. full integration test).
* <p>
* This uses the regular {@link MockMvc} (Hamcrest integration).
*
* @author Phillip Webb
* @author Moritz Halbritter

View File

@ -0,0 +1,92 @@
/*
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrint;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.context.ApplicationContext;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link SpringBootTest @SpringBootTest} with
* {@link AutoConfigureMockMvc @AutoConfigureMockMvc} (i.e. full integration test).
* <p>
* This uses {@link MockMvcTester} (AssertJ integration).
*
* @author Stephane Nicoll
*/
@SpringBootTest
@AutoConfigureMockMvc(print = MockMvcPrint.SYSTEM_ERR, printOnlyOnFailure = false)
@WithMockUser(username = "user", password = "secret")
@ExtendWith(OutputCaptureExtension.class)
class MockMvcTesterSpringBootTestIntegrationTests {
@MockBean
private ExampleMockableService service;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private MockMvcTester mvc;
@Test
void shouldFindController1(CapturedOutput output) {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("one");
assertThat(output).contains("Request URI = /one");
}
@Test
void shouldFindController2() {
assertThat(this.mvc.get().uri("/two")).hasStatusOk().hasBodyTextEqualTo("hellotwo");
}
@Test
void shouldFindControllerAdvice() {
assertThat(this.mvc.get().uri("/error")).hasStatusOk().hasBodyTextEqualTo("recovered");
}
@Test
void shouldHaveRealService() {
assertThat(this.applicationContext.getBean(ExampleRealService.class)).isNotNull();
}
@Test
void shouldTestWithWebTestClient(@Autowired WebTestClient webTestClient) {
webTestClient.get().uri("/one").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("one");
}
@Test
void shouldNotFailIfFormattingValueThrowsException(CapturedOutput output) {
assertThat(this.mvc.get().uri("/formatting")).hasStatusOk().hasBodyTextEqualTo("formatting");
assertThat(output).contains(
"Session Attrs = << Exception 'java.lang.IllegalStateException: Formatting failed' occurred while formatting >>");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
package org.springframework.boot.test.autoconfigure.web.servlet.mockmvc;
import java.util.function.Consumer;
import jakarta.servlet.ServletException;
import jakarta.validation.ConstraintViolationException;
import org.junit.jupiter.api.Test;
@ -24,13 +26,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.test.web.servlet.assertj.MvcTestResult;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest @WebMvcTest} when no explicit controller is defined.
@ -43,35 +42,36 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestAllControllersIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Autowired(required = false)
private ErrorAttributes errorAttributes;
@Test
void shouldFindController1() throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one")).andExpect(status().isOk());
void shouldFindController1() {
assertThat(this.mvc.get().uri("/one")).satisfies(hasBody("one"));
}
@Test
void shouldFindController2() throws Exception {
this.mvc.perform(get("/two")).andExpect(content().string("hellotwo")).andExpect(status().isOk());
void shouldFindController2() {
assertThat(this.mvc.get().uri("/two")).satisfies(hasBody("hellotwo"));
}
@Test
void shouldFindControllerAdvice() throws Exception {
this.mvc.perform(get("/error")).andExpect(content().string("recovered")).andExpect(status().isOk());
void shouldFindControllerAdvice() {
assertThat(this.mvc.get().uri("/error")).satisfies(hasBody("recovered"));
}
@Test
void shouldRunValidationSuccess() throws Exception {
this.mvc.perform(get("/three/OK")).andExpect(status().isOk()).andExpect(content().string("Hello OK"));
void shouldRunValidationSuccess() {
assertThat(this.mvc.get().uri("/three/OK")).satisfies(hasBody("Hello OK"));
}
@Test
void shouldRunValidationFailure() {
assertThatExceptionOfType(ServletException.class).isThrownBy(() -> this.mvc.perform(get("/three/invalid")))
.withCauseInstanceOf(ConstraintViolationException.class);
assertThat(this.mvc.get().uri("/three/invalid")).failure()
.isInstanceOf(ServletException.class)
.hasCauseInstanceOf(ConstraintViolationException.class);
}
@Test
@ -80,4 +80,8 @@ class WebMvcTestAllControllersIntegrationTests {
}
private Consumer<MvcTestResult> hasBody(String expected) {
return (result) -> assertThat(result).hasStatusOk().hasBodyTextEqualTo(expected);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,11 +23,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest @WebMvcTest} to validate converters are discovered.
@ -39,12 +37,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestConverterIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldFindConverter() throws Exception {
void shouldFindConverter() {
String id = UUID.randomUUID().toString();
this.mvc.perform(get("/two/" + id)).andExpect(content().string(id + "two")).andExpect(status().isOk());
assertThat(this.mvc.get().uri("/two/" + id)).hasStatusOk().hasBodyTextEqualTo(id + "two");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,14 +20,13 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.servlet.DispatcherServlet;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for Test {@link DispatcherServlet} customizations.
@ -41,13 +40,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestCustomDispatcherServletIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void dispatcherServletIsCustomized() throws Exception {
this.mvc.perform(get("/does-not-exist"))
.andExpect(status().isBadRequest())
.andExpect(content().string("Invalid request: /does-not-exist"));
void dispatcherServletIsCustomized() {
assertThat(this.mvc.get().uri("/does-not-exist")).hasStatus(HttpStatus.BAD_REQUEST)
.hasBodyTextEqualTo("Invalid request: /does-not-exist");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,12 +20,10 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpHeaders;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link WebMvcTest @WebMvcTest} and Spring HATEOAS.
@ -37,18 +35,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestHateoasIntegrationTests {
@Autowired
private MockMvc mockMvc;
private MockMvcTester mvc;
@Test
void plainResponse() throws Exception {
this.mockMvc.perform(get("/hateoas/plain"))
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, "application/json"));
void plainResponse() {
assertThat(this.mvc.get().uri("/hateoas/plain")).hasContentType("application/json");
}
@Test
void hateoasResponse() throws Exception {
this.mockMvc.perform(get("/hateoas/resource"))
.andExpect(header().string(HttpHeaders.CONTENT_TYPE, "application/hal+json"));
void hateoasResponse() {
assertThat(this.mvc.get().uri("/hateoas/resource")).hasContentType("application/hal+json");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,12 +21,11 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest @WebMvcTest} using {@link Nested}.
@ -38,16 +37,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestNestedIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldNotFindController1() throws Exception {
this.mvc.perform(get("/one")).andExpect(status().isNotFound());
void shouldNotFindController1() {
assertThat(this.mvc.get().uri("/one")).hasStatus(HttpStatus.NOT_FOUND);
}
@Test
void shouldFindController2() throws Exception {
this.mvc.perform(get("/two")).andExpect(content().string("hellotwo")).andExpect(status().isOk());
void shouldFindController2() {
assertThat(this.mvc.get().uri("/two")).hasStatusOk().hasBodyTextEqualTo("hellotwo");
}
@Nested
@ -55,15 +54,14 @@ class WebMvcTestNestedIntegrationTests {
class NestedTests {
@Test
void shouldNotFindController1() throws Exception {
WebMvcTestNestedIntegrationTests.this.mvc.perform(get("/one")).andExpect(status().isNotFound());
void shouldNotFindController1() {
assertThat(WebMvcTestNestedIntegrationTests.this.mvc.get().uri("/one")).hasStatus(HttpStatus.NOT_FOUND);
}
@Test
void shouldFindController2() throws Exception {
WebMvcTestNestedIntegrationTests.this.mvc.perform(get("/two"))
.andExpect(content().string("hellotwo"))
.andExpect(status().isOk());
void shouldFindController2() {
assertThat(WebMvcTestNestedIntegrationTests.this.mvc.get().uri("/two")).hasStatusOk()
.hasBodyTextEqualTo("hellotwo");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,12 +20,11 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest @WebMvcTest} when a specific controller is defined.
@ -37,16 +36,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestOneControllerIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldNotFindController1() throws Exception {
this.mvc.perform(get("/one")).andExpect(status().isNotFound());
void shouldNotFindController1() {
assertThat(this.mvc.get().uri("/one")).hasStatus(HttpStatus.NOT_FOUND);
}
@Test
void shouldFindController2() throws Exception {
this.mvc.perform(get("/two")).andExpect(content().string("hellotwo")).andExpect(status().isOk());
void shouldFindController2() {
assertThat(this.mvc.get().uri("/two")).hasStatusOk().hasBodyTextEqualTo("hellotwo");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,11 +21,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link WebMvcTest @WebMvcTest} and Pageable support.
@ -37,13 +35,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestPageableIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldSupportPageable() throws Exception {
this.mvc.perform(get("/paged").param("page", "2").param("size", "42"))
.andExpect(status().isOk())
.andExpect(content().string("2:42"));
void shouldSupportPageable() {
assertThat(this.mvc.get().uri("/paged").param("page", "2").param("size", "42")).hasStatusOk()
.hasBodyTextEqualTo("2:42");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,12 +25,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest @WebMvcTest} default print output.
@ -44,11 +41,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestPrintAlwaysIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldPrint(CapturedOutput output) throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one")).andExpect(status().isOk());
void shouldPrint(CapturedOutput output) {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("one");
assertThat(output).contains("Request URI = /one");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -32,12 +32,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest @WebMvcTest} default print output.
@ -75,11 +72,11 @@ class WebMvcTestPrintDefaultIntegrationTests {
static class ShouldNotPrint {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void test() throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one")).andExpect(status().isOk());
void test() {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("one");
}
}
@ -90,11 +87,11 @@ class WebMvcTestPrintDefaultIntegrationTests {
static class ShouldPrint {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void test() throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("none")).andExpect(status().isOk());
void test() {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("none");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,12 +25,9 @@ import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest @WebMvcTest} when a specific controller is defined.
@ -44,11 +41,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestPrintDefaultOverrideIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldFindController1(CapturedOutput output) throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one")).andExpect(status().isOk());
void shouldFindController1(CapturedOutput output) {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("one");
assertThat(output).doesNotContain("Request URI = /one");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,12 +26,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebMvcTest @WebMvcTest} when a specific print option is defined.
@ -45,11 +42,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestPrintOverrideIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldNotPrint(CapturedOutput output) throws Exception {
this.mvc.perform(get("/one")).andExpect(content().string("one")).andExpect(status().isOk());
void shouldNotPrint(CapturedOutput output) {
assertThat(this.mvc.get().uri("/one")).hasStatusOk().hasBodyTextEqualTo("one");
assertThat(output).doesNotContain("Request URI = /one");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,10 +20,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest @WebMvcTest} servlet filter registration.
@ -34,11 +33,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestServletFilterIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldApplyFilter() throws Exception {
this.mvc.perform(get("/one")).andExpect(header().string("x-test", "abc"));
void shouldApplyFilter() {
assertThat(this.mvc.get().uri("/one")).hasHeader("x-test", "abc");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,10 +23,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link WebMvcTest @WebMvcTest} with a disabled filter registration.
@ -37,11 +36,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class WebMvcTestServletFilterRegistrationDisabledIntegrationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldNotApplyFilter() throws Exception {
this.mvc.perform(get("/one")).andExpect(header().string("x-test", (String) null));
void shouldNotApplyFilter() {
assertThat(this.mvc.get().uri("/one")).doesNotContainHeader("x-test");
}
@TestConfiguration(proxyBeanMethods = false)

View File

@ -25,11 +25,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
/**
* Tests for {@link WebMvcTest @WebMvcTest} with
@ -46,11 +45,11 @@ class WebMvcTestWithAutoConfigureMockMvcIntegrationTests {
private ApplicationContext context;
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void shouldNotAddFilters() throws Exception {
this.mvc.perform(get("/one")).andExpect(header().doesNotExist("x-test"));
void shouldNotAddFilters() {
assertThat(this.mvc.get().uri("/one")).doesNotContainHeader("x-test");
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,8 +27,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext;
@ -36,9 +35,6 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link WebAppConfiguration @WebAppConfiguration} integration.
@ -57,16 +53,16 @@ class SpringBootContextLoaderMockMvcTests {
@Autowired
private ServletContext servletContext;
private MockMvc mvc;
private MockMvcTester mvc;
@BeforeEach
void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
this.mvc = MockMvcTester.from(this.context);
}
@Test
void testMockHttpEndpoint() throws Exception {
this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Hello World"));
void testMockHttpEndpoint() {
assertThat(this.mvc.get().uri("/")).hasStatusOk().hasBodyTextEqualTo("Hello World");
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,12 +28,9 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link SampleActuatorLog4J2Application}.
@ -49,7 +46,7 @@ class SampleActuatorLog4J2ApplicationTests {
private static final Logger logger = LogManager.getLogger(SampleActuatorLog4J2ApplicationTests.class);
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Test
void testLogger(CapturedOutput output) {
@ -58,12 +55,11 @@ class SampleActuatorLog4J2ApplicationTests {
}
@Test
void validateLoggersEndpoint() throws Exception {
this.mvc
.perform(get("/actuator/loggers/org.apache.coyote.http11.Http11NioProtocol").header("Authorization",
getBasicAuth()))
.andExpect(status().isOk())
.andExpect(content().string("{\"configuredLevel\":\"WARN\",\"effectiveLevel\":\"WARN\"}"));
void validateLoggersEndpoint() {
assertThat(this.mvc.get()
.uri("/actuator/loggers/org.apache.coyote.http11.Http11NioProtocol")
.header("Authorization", getBasicAuth())).hasStatusOk()
.hasBodyTextEqualTo("{\"configuredLevel\":\"WARN\",\"effectiveLevel\":\"WARN\"}");
}
private String getBasicAuth() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,19 +16,14 @@
package smoketest.data.jdbc;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link SampleDataJdbcApplication}.
@ -36,23 +31,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Andy Wilkinson
*/
@SpringBootTest
@AutoConfigureMockMvc
class SampleDataJdbcApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@BeforeEach
void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
private MockMvcTester mvc;
@Test
void testCustomers() throws Exception {
this.mvc.perform(get("/").param("name", "merEDith"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("Meredith")));
void testCustomers() {
assertThat(this.mvc.get().uri("/").param("name", "merEDith")).hasStatusOk().bodyText().contains("Meredith");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,20 +20,15 @@ import java.lang.management.ManagementFactory;
import javax.management.ObjectName;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration test to run the application.
@ -43,24 +38,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
*/
// Enable JMX so we can test the MBeans (you can't do this in a properties file)
@SpringBootTest(properties = "spring.jmx.enabled:true")
@AutoConfigureMockMvc
@ActiveProfiles("scratch")
// Separate profile for web tests to avoid clashing databases
class SampleDataJpaApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@BeforeEach
void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
private MockMvcTester mvc;
@Test
void testHome() throws Exception {
this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Bath"));
void testHome() {
assertThat(this.mvc.get().uri("/")).hasStatusOk().hasBodyTextEqualTo("Bath");
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,22 +16,18 @@
package smoketest.data.jpa;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import smoketest.data.jpa.service.CityRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.then;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Tests for {@link SampleDataJpaApplication} that use {@link SpyBean @SpyBean}.
@ -39,25 +35,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Andy Wilkinson
*/
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase
class SpyBeanSampleDataJpaApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
private MockMvcTester mvc;
@SpyBean
private CityRepository repository;
@BeforeEach
void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
void testHome() throws Exception {
this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("Bath"));
void testHome() {
assertThat(this.mvc.get().uri("/")).hasStatusOk().hasBodyTextEqualTo("Bath");
then(this.repository).should().findByNameAndCountryAllIgnoringCase("Bath", "UK");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,22 +16,15 @@
package smoketest.data.rest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import smoketest.data.rest.domain.City;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration test to run the application.
@ -40,38 +33,41 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Andy Wilkinson
*/
@SpringBootTest
@AutoConfigureMockMvc
// Separate profile for web tests to avoid clashing databases
class SampleDataRestApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvcTester mvc;
private MockMvc mvc;
@BeforeEach
void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
@Test
void testHome() {
assertThat(this.mvc.get().uri("/api")).hasStatusOk().bodyText().contains("hotels");
}
@Test
void testHome() throws Exception {
this.mvc.perform(get("/api")).andExpect(status().isOk()).andExpect(content().string(containsString("hotels")));
void findByNameAndCountry() {
assertThat(this.mvc.get()
.uri("/api/cities/search/findByNameAndCountryAllIgnoringCase?name=Melbourne&country=Australia"))
.hasStatusOk()
.bodyJson()
.extractingPath("$")
.convertTo(City.class)
.satisfies((city) -> {
assertThat(city.getName()).isEqualTo("Melbourne");
assertThat(city.getState()).isEqualTo("Victoria");
});
}
@Test
void findByNameAndCountry() throws Exception {
this.mvc.perform(get("/api/cities/search/findByNameAndCountryAllIgnoringCase?name=Melbourne&country=Australia"))
.andExpect(status().isOk())
.andExpect(jsonPath("state", equalTo("Victoria")))
.andExpect(jsonPath("name", equalTo("Melbourne")));
}
@Test
void findByContaining() throws Exception {
this.mvc
.perform(get("/api/cities/search/findByNameContainingAndCountryContainingAllIgnoringCase?name=&country=UK"))
.andExpect(status().isOk())
.andExpect(jsonPath("_embedded.cities", hasSize(3)));
void findByContaining() {
assertThat(this.mvc.get()
.uri("/api/cities/search/findByNameContainingAndCountryContainingAllIgnoringCase?name=&country=UK"))
.hasStatusOk()
.bodyJson()
.extractingPath("_embedded.cities")
.asArray()
.hasSize(3);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,18 +16,14 @@
package smoketest.jpa;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
/**
@ -37,22 +33,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Dave Syer
*/
@SpringBootTest
@WebAppConfiguration
@AutoConfigureMockMvc
class SampleJpaApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@BeforeEach
void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
private MockMvcTester mvc;
@Test
void testHome() throws Exception {
this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(xpath("//tbody/tr").nodeCount(4));
assertThat(this.mvc.get().uri("/")).hasStatusOk().matches(xpath("//tbody/tr").nodeCount(4));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,21 +22,20 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@WebMvcTest
public class SampleJUnitVintageApplicationTests {
@Autowired
private MockMvc mockMvc;
private MockMvcTester mvc;
@Test
public void testMessage() throws Exception {
this.mockMvc.perform(get("/hi")).andExpect(content().string("Hello World"));
public void testMessage() {
assertThat(this.mvc.get().uri("/hi")).hasBodyTextEqualTo("Hello World");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,13 +27,10 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* {@code @SpringBootTest} based tests for {@link UserVehicleController}.
@ -46,7 +43,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
class UserVehicleControllerApplicationTests {
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Autowired
private ApplicationContext applicationContext;
@ -55,11 +52,10 @@ class UserVehicleControllerApplicationTests {
private UserVehicleService userVehicleService;
@Test
void getVehicleWhenRequestingTextShouldReturnMakeAndModel() throws Exception {
void getVehicleWhenRequestingTextShouldReturnMakeAndModel() {
given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
assertThat(this.mvc.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)).hasStatusOk()
.hasBodyTextEqualTo("Honda Civic");
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,15 +27,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.hamcrest.Matchers.containsString;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* {@code @WebMvcTest} based tests for {@link UserVehicleController}.
@ -48,7 +46,7 @@ class UserVehicleControllerTests {
private static final VehicleIdentificationNumber VIN = new VehicleIdentificationNumber("00000000000000000");
@Autowired
private MockMvc mvc;
private MockMvcTester mvc;
@Autowired
private ApplicationContext applicationContext;
@ -57,40 +55,39 @@ class UserVehicleControllerTests {
private UserVehicleService userVehicleService;
@Test
void getVehicleWhenRequestingTextShouldReturnMakeAndModel() throws Exception {
void getVehicleWhenRequestingTextShouldReturnMakeAndModel() {
given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("Honda Civic"));
assertThat(this.mvc.get().uri("/sboot/vehicle").accept(MediaType.TEXT_PLAIN)).hasStatusOk()
.hasBodyTextEqualTo("Honda Civic");
}
@Test
void getVehicleWhenRequestingJsonShouldReturnMakeAndModel() throws Exception {
void getVehicleWhenRequestingJsonShouldReturnMakeAndModel() {
given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json("{'make':'Honda','model':'Civic'}"));
assertThat(this.mvc.get().uri("/sboot/vehicle").accept(MediaType.APPLICATION_JSON)).hasStatusOk()
.bodyJson()
.isLenientlyEqualTo("{'make':'Honda','model':'Civic'}");
}
@Test
void getVehicleWhenRequestingHtmlShouldReturnMakeAndModel() throws Exception {
void getVehicleWhenRequestingHtmlShouldReturnMakeAndModel() {
given(this.userVehicleService.getVehicleDetails("sboot")).willReturn(new VehicleDetails("Honda", "Civic"));
this.mvc.perform(get("/sboot/vehicle.html").accept(MediaType.TEXT_HTML))
.andExpect(status().isOk())
.andExpect(content().string(containsString("<h1>Honda Civic</h1>")));
assertThat(this.mvc.get().uri("/sboot/vehicle.html").accept(MediaType.TEXT_HTML)).hasStatusOk()
.bodyText()
.contains("<h1>Honda Civic</h1>");
}
@Test
void getVehicleWhenUserNotFoundShouldReturnNotFound() throws Exception {
void getVehicleWhenUserNotFoundShouldReturnNotFound() {
given(this.userVehicleService.getVehicleDetails("sboot")).willThrow(new UserNameNotFoundException("sboot"));
this.mvc.perform(get("/sboot/vehicle")).andExpect(status().isNotFound());
assertThat(this.mvc.get().uri("/sboot/vehicle")).hasStatus(HttpStatus.NOT_FOUND);
}
@Test
void getVehicleWhenVinNotFoundShouldReturnNotFound() throws Exception {
void getVehicleWhenVinNotFoundShouldReturnNotFound() {
given(this.userVehicleService.getVehicleDetails("sboot"))
.willThrow(new VehicleIdentificationNumberNotFoundException(VIN));
this.mvc.perform(get("/sboot/vehicle")).andExpect(status().isNotFound());
assertThat(this.mvc.get().uri("/sboot/vehicle")).hasStatus(HttpStatus.NOT_FOUND);
}
@Test

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,23 +18,18 @@ package smoketest.groovytemplates;
import java.util.regex.Pattern;
import org.assertj.core.api.HamcrestCondition;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* A Basic Spring MVC Test for the Sample Controller.
@ -43,37 +38,33 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Doo-Hwan, Kwak
*/
@SpringBootTest
@AutoConfigureMockMvc
class MessageControllerWebTests {
@Autowired
private WebApplicationContext wac;
private MockMvcTester mvc;
private MockMvc mockMvc;
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
@Test
void testHome() {
assertThat(this.mvc.get().uri("/")).hasStatusOk().bodyText().contains("<title>Messages");
}
@Test
void testHome() throws Exception {
this.mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("<title>Messages")));
void testCreate() {
assertThat(this.mvc.post().uri("/").param("text", "FOO text").param("summary", "FOO"))
.hasStatus(HttpStatus.FOUND)
.headers()
.hasEntrySatisfying("Location",
(values) -> assertThat(values).hasSize(1)
.element(0)
.satisfies(HamcrestCondition.matching(RegexMatcher.matches("/[0-9]+"))));
}
@Test
void testCreate() throws Exception {
this.mockMvc.perform(post("/").param("text", "FOO text").param("summary", "FOO"))
.andExpect(status().isFound())
.andExpect(header().string("location", RegexMatcher.matches("/[0-9]+")));
}
@Test
void testCreateValidation() throws Exception {
this.mockMvc.perform(post("/").param("text", "").param("summary", ""))
.andExpect(status().isOk())
.andExpect(content().string(containsString("is required")));
void testCreateValidation() {
assertThat(this.mvc.post().uri("/").param("text", "").param("summary", "")).hasStatusOk()
.bodyText()
.contains("is required");
}
private static class RegexMatcher extends TypeSafeMatcher<String> {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,23 +18,18 @@ package smoketest.web.thymeleaf;
import java.util.regex.Pattern;
import org.assertj.core.api.HamcrestCondition;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.test.web.servlet.assertj.MockMvcTester;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.assertj.core.api.Assertions.assertThat;
/**
* A Basic Spring MVC Test for the Sample Controller.
@ -43,37 +38,33 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* @author Doo-Hwan, Kwak
*/
@SpringBootTest
@AutoConfigureMockMvc
class MessageControllerWebTests {
@Autowired
private WebApplicationContext wac;
private MockMvcTester mvc;
private MockMvc mockMvc;
@BeforeEach
void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
@Test
void testHome() {
assertThat(this.mvc.get().uri("/")).hasStatusOk().bodyText().contains("<title>Messages");
}
@Test
void testHome() throws Exception {
this.mockMvc.perform(get("/"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("<title>Messages")));
void testCreate() {
assertThat(this.mvc.post().uri("/").param("text", "FOO text").param("summary", "FOO"))
.hasStatus(HttpStatus.FOUND)
.headers()
.hasEntrySatisfying("Location",
(values) -> assertThat(values).hasSize(1)
.element(0)
.satisfies(HamcrestCondition.matching(RegexMatcher.matches("/[0-9]+"))));
}
@Test
void testCreate() throws Exception {
this.mockMvc.perform(post("/").param("text", "FOO text").param("summary", "FOO"))
.andExpect(status().isFound())
.andExpect(header().string("location", RegexMatcher.matches("/[0-9]+")));
}
@Test
void testCreateValidation() throws Exception {
this.mockMvc.perform(post("/").param("text", "").param("summary", ""))
.andExpect(status().isOk())
.andExpect(content().string(containsString("is required")));
void testCreateValidation() {
assertThat(this.mvc.post().uri("/").param("text", "").param("summary", "")).hasStatusOk()
.bodyText()
.contains("is required");
}
private static class RegexMatcher extends TypeSafeMatcher<String> {