Skip to content

Commit 340b842

Browse files
committed
Merge pull request #583 from nosan
* gh-583: Polish "Improve diagnostics for null configuration" Improve diagnostics for null configuration Closes gh-583
2 parents c4d664c + fce2556 commit 340b842

File tree

8 files changed

+84
-14
lines changed

8 files changed

+84
-14
lines changed

spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@ public class RestDocumentationResultHandler implements ResultHandler {
4949

5050
@Override
5151
public void handle(MvcResult result) throws Exception {
52-
@SuppressWarnings("unchecked")
53-
Map<String, Object> configuration = (Map<String, Object>) result.getRequest()
54-
.getAttribute(ATTRIBUTE_NAME_CONFIGURATION);
55-
this.delegate.handle(result.getRequest(), result.getResponse(), configuration);
52+
this.delegate.handle(result.getRequest(), result.getResponse(), retrieveConfiguration(result));
5653
}
5754

5855
/**
@@ -75,9 +72,7 @@ public RestDocumentationResultHandler document(Snippet... snippets) {
7572

7673
@Override
7774
public void handle(MvcResult result) throws Exception {
78-
@SuppressWarnings("unchecked")
79-
Map<String, Object> configuration = new HashMap<>(
80-
(Map<String, Object>) result.getRequest().getAttribute(ATTRIBUTE_NAME_CONFIGURATION));
75+
Map<String, Object> configuration = new HashMap<>(retrieveConfiguration(result));
8176
configuration.remove(RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
8277
getDelegate().handle(result.getRequest(), result.getResponse(), configuration);
8378
}
@@ -93,4 +88,13 @@ protected final RestDocumentationGenerator<MockHttpServletRequest, MockHttpServl
9388
return this.delegate;
9489
}
9590

91+
private Map<String, Object> retrieveConfiguration(MvcResult result) {
92+
@SuppressWarnings("unchecked")
93+
Map<String, Object> configuration = (Map<String, Object>) result.getRequest()
94+
.getAttribute(ATTRIBUTE_NAME_CONFIGURATION);
95+
Assert.state(configuration != null, () -> "REST Docs configuration not found. Did you forget to apply a "
96+
+ MockMvcRestDocumentationConfigurer.class.getSimpleName() + " when building the MockMvc instance?");
97+
return configuration;
98+
}
99+
96100
}

spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java

+21
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
7070

7171
import static org.assertj.core.api.Assertions.assertThat;
72+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
7273
import static org.assertj.core.api.Assertions.fail;
7374
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
7475
import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
@@ -491,6 +492,26 @@ public void customContextPath() throws Exception {
491492
+ " -H 'Accept: application/json'"))));
492493
}
493494

495+
@Test
496+
public void exceptionShouldBeThrownWhenCallDocumentMockMvcNotConfigured() {
497+
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
498+
assertThatThrownBy(() -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)).andDo(document("basic")))
499+
.isInstanceOf(IllegalStateException.class).hasMessage("REST Docs configuration not found. Did you "
500+
+ "forget to apply a MockMvcRestDocumentationConfigurer when building the MockMvc instance?");
501+
502+
}
503+
504+
@Test
505+
public void exceptionShouldBeThrownWhenCallDocumentSnippetsMockMvcNotConfigured() {
506+
RestDocumentationResultHandler documentation = document("{method-name}-{step}");
507+
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
508+
assertThatThrownBy(() -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
509+
.andDo(documentation.document(responseHeaders(headerWithName("a").description("one")))))
510+
.isInstanceOf(IllegalStateException.class)
511+
.hasMessage("REST Docs configuration not found. Did you forget to apply a "
512+
+ "MockMvcRestDocumentationConfigurer when building the MockMvc instance?");
513+
}
514+
494515
@Test
495516
public void multiPart() throws Exception {
496517
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)

spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@ public final Response filter(FilterableRequestSpecification requestSpec,
6767
* @return the configuration
6868
*/
6969
protected Map<String, Object> getConfiguration(FilterableRequestSpecification requestSpec, FilterContext context) {
70-
Map<String, Object> configuration = new HashMap<>(
71-
context.<Map<String, Object>>getValue(CONTEXT_KEY_CONFIGURATION));
70+
Map<String, Object> configuration = new HashMap<>(retrieveConfiguration(context));
7271
configuration.put(RestDocumentationContext.class.getName(),
7372
context.<RestDocumentationContext>getValue(RestDocumentationContext.class.getName()));
7473
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, requestSpec.getUserDefinedPath());
@@ -97,4 +96,13 @@ protected Map<String, Object> getConfiguration(FilterableRequestSpecification re
9796
};
9897
}
9998

99+
private static Map<String, Object> retrieveConfiguration(FilterContext context) {
100+
Map<String, Object> configuration = context.getValue(CONTEXT_KEY_CONFIGURATION);
101+
Assert.state(configuration != null,
102+
() -> "REST Docs configuration not found. Did you forget to add a "
103+
+ RestAssuredRestDocumentationConfigurer.class.getSimpleName()
104+
+ " as a filter when building the RequestSpecification?");
105+
return configuration;
106+
}
107+
100108
}

spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java

+20
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
import static io.restassured.RestAssured.given;
4949
import static org.assertj.core.api.Assertions.assertThat;
50+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
5051
import static org.assertj.core.api.Assertions.fail;
5152
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
5253
import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders;
@@ -339,6 +340,25 @@ public void customSnippetTemplate() throws Exception {
339340
.hasContent("Custom curl request");
340341
}
341342

343+
@Test
344+
public void exceptionShouldBeThrownWhenCallDocumentRequestSpecificationNotConfigured() {
345+
assertThatThrownBy(() -> given().port(tomcat.getPort()).filter(document("default")).get("/"))
346+
.isInstanceOf(IllegalStateException.class)
347+
.hasMessage("REST Docs configuration not found. Did you forget to add a "
348+
+ "RestAssuredRestDocumentationConfigurer as a filter when building the RequestSpecification?");
349+
}
350+
351+
@Test
352+
public void exceptionShouldBeThrownWhenCallDocumentSnippetsRequestSpecificationNotConfigured() {
353+
RestDocumentationFilter documentation = document("{method-name}-{step}");
354+
assertThatThrownBy(() -> given().port(tomcat.getPort())
355+
.filter(documentation.document(responseHeaders(headerWithName("a").description("one")))).get("/"))
356+
.isInstanceOf(IllegalStateException.class)
357+
.hasMessage("REST Docs configuration not found. Did you forget to add a "
358+
+ "RestAssuredRestDocumentationConfigurer as a filter when building the "
359+
+ "RequestSpecification?");
360+
}
361+
342362
private void assertExpectedSnippetFilesExist(File directory, String... snippets) {
343363
for (String snippet : snippets) {
344364
assertThat(new File(directory, snippet)).isFile();

spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.restdocs.webtestclient;
1818

19-
import java.util.HashMap;
2019
import java.util.Map;
2120
import java.util.function.Consumer;
2221

@@ -134,8 +133,8 @@ public static <T extends ExchangeResult> Consumer<T> document(String identifier,
134133
}
135134

136135
private static Map<String, Object> retrieveConfiguration(ExchangeResult result) {
137-
Map<String, Object> configuration = new HashMap<>(
138-
WebTestClientRestDocumentationConfigurer.retrieveConfiguration(result.getRequestHeaders()));
136+
Map<String, Object> configuration = WebTestClientRestDocumentationConfigurer
137+
.retrieveConfiguration(result.getRequestHeaders());
139138
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, result.getUriTemplate());
140139
return configuration;
141140
}

spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurer.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.restdocs.RestDocumentationContextProvider;
3030
import org.springframework.restdocs.config.RestDocumentationConfigurer;
3131
import org.springframework.test.web.reactive.server.WebTestClient;
32+
import org.springframework.util.Assert;
3233
import org.springframework.util.StringUtils;
3334
import org.springframework.web.reactive.function.client.ClientRequest;
3435
import org.springframework.web.reactive.function.client.ClientResponse;
@@ -78,7 +79,10 @@ private Map<String, Object> createConfiguration() {
7879

7980
static Map<String, Object> retrieveConfiguration(HttpHeaders headers) {
8081
String requestId = headers.getFirst(WebTestClient.WEBTESTCLIENT_REQUEST_ID);
81-
return configurations.remove(requestId);
82+
Map<String, Object> configuration = configurations.remove(requestId);
83+
Assert.state(configuration != null, () -> "REST Docs configuration not found. Did you forget to register a "
84+
+ WebTestClientRestDocumentationConfigurer.class.getSimpleName() + " as a filter?");
85+
return configuration;
8286
}
8387

8488
@Override

spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationConfigurerTests.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.web.reactive.function.client.ExchangeFunction;
3030

3131
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
3233
import static org.mockito.Mockito.mock;
3334
import static org.mockito.Mockito.verify;
3435

@@ -51,7 +52,8 @@ public void configurationCanBeRetrievedButOnlyOnce() {
5152
.header(WebTestClient.WEBTESTCLIENT_REQUEST_ID, "1").build();
5253
this.configurer.filter(request, mock(ExchangeFunction.class));
5354
assertThat(WebTestClientRestDocumentationConfigurer.retrieveConfiguration(request.headers())).isNotNull();
54-
assertThat(WebTestClientRestDocumentationConfigurer.retrieveConfiguration(request.headers())).isNull();
55+
assertThatIllegalStateException()
56+
.isThrownBy(() -> WebTestClientRestDocumentationConfigurer.retrieveConfiguration(request.headers()));
5557
}
5658

5759
@Test

spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.nio.charset.StandardCharsets;
2424
import java.util.Arrays;
2525
import java.util.HashSet;
26+
import java.util.List;
2627
import java.util.Set;
2728
import java.util.function.Consumer;
2829
import java.util.stream.Collectors;
@@ -58,6 +59,7 @@
5859
import org.springframework.web.reactive.function.server.ServerResponse;
5960

6061
import static org.assertj.core.api.Assertions.assertThat;
62+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
6163
import static org.assertj.core.api.Assertions.fail;
6264
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
6365
import static org.springframework.restdocs.request.RequestDocumentation.partWithName;
@@ -173,6 +175,16 @@ public void httpieSnippetWithCookies() throws Exception {
173175
+ " 'Accept:application/json' \\%n" + " 'Cookie:cookieName=cookieVal'"))));
174176
}
175177

178+
@Test
179+
public void illegalStateExceptionShouldBeThrownWhenCallDocumentWebClientNotConfigured() {
180+
assertThatThrownBy(() -> this.webTestClient
181+
.mutateWith((builder, httpHandlerBuilder, connector) -> builder.filters(List::clear).build()).get()
182+
.uri("/").exchange().expectBody().consumeWith(document("default-snippets")))
183+
.isInstanceOf(IllegalStateException.class)
184+
.hasMessage("REST Docs configuration not found. Did you forget to register a "
185+
+ "WebTestClientRestDocumentationConfigurer as a filter?");
186+
}
187+
176188
private void assertExpectedSnippetFilesExist(File directory, String... snippets) {
177189
Set<File> actual = new HashSet<>(Arrays.asList(directory.listFiles()));
178190
Set<File> expected = Stream.of(snippets).map((snippet) -> new File(directory, snippet))

0 commit comments

Comments
 (0)