Skip to content

Commit 72a0e39

Browse files
committed
adds Assert.state(configuration != null) to avoid a NullPointerException.
1 parent ba48a72 commit 72a0e39

File tree

6 files changed

+104
-16
lines changed

6 files changed

+104
-16
lines changed

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

+14-7
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,8 @@ 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(),
53+
getRequiredConfiguration(result));
5654
}
5755

5856
/**
@@ -75,10 +73,8 @@ public RestDocumentationResultHandler document(Snippet... snippets) {
7573

7674
@Override
7775
public void handle(MvcResult result) throws Exception {
78-
@SuppressWarnings("unchecked")
7976
Map<String, Object> configuration = new HashMap<>(
80-
(Map<String, Object>) result.getRequest()
81-
.getAttribute(ATTRIBUTE_NAME_CONFIGURATION));
77+
getRequiredConfiguration(result));
8278
configuration.remove(
8379
RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS);
8480
getDelegate().handle(result.getRequest(), result.getResponse(),
@@ -96,4 +92,15 @@ protected final RestDocumentationGenerator<MockHttpServletRequest, MockHttpServl
9692
return this.delegate;
9793
}
9894

95+
private static Map<String, Object> getRequiredConfiguration(MvcResult result) {
96+
@SuppressWarnings("unchecked")
97+
Map<String, Object> configuration = (Map<String, Object>) result.getRequest()
98+
.getAttribute(ATTRIBUTE_NAME_CONFIGURATION);
99+
Assert.state(configuration != null,
100+
() -> String.format("There is no REST Docs configuration. Looks like "
101+
+ "'%s' was not invoked. Please check your configuration.",
102+
MockMvcRestDocumentationConfigurer.class.getName()));
103+
return configuration;
104+
}
105+
99106
}

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

+29
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;
@@ -594,6 +595,34 @@ public void customContextPath() throws Exception {
594595
+ " -H 'Accept: application/json'"))));
595596
}
596597

598+
@Test
599+
public void exceptionShouldBeThrownWhenCallDocumentMockMvcNotConfigured() {
600+
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
601+
assertThatThrownBy(() -> mockMvc
602+
.perform(get("/").accept(MediaType.APPLICATION_JSON))
603+
.andDo(document("basic"))).isInstanceOf(IllegalStateException.class)
604+
.hasMessageContaining(
605+
"There is no REST Docs configuration. Looks like "
606+
+ "'org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer' "
607+
+ "was not invoked. Please check your configuration.");
608+
609+
}
610+
611+
@Test
612+
public void exceptionShouldBeThrownWhenCallDocumentSnippetsMockMvcNotConfigured() {
613+
RestDocumentationResultHandler documentation = document("{method-name}-{step}");
614+
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
615+
assertThatThrownBy(() -> mockMvc
616+
.perform(get("/").accept(MediaType.APPLICATION_JSON))
617+
.andDo(documentation.document(
618+
responseHeaders(headerWithName("a").description("one")))))
619+
.isInstanceOf(IllegalStateException.class)
620+
.hasMessageContaining(
621+
"There is no REST Docs configuration. Looks like "
622+
+ "'org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer' "
623+
+ "was not invoked. Please check your configuration.");
624+
}
625+
597626
@Test
598627
public void multiPart() throws Exception {
599628
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context)

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

+10-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public final Response filter(FilterableRequestSpecification requestSpec,
7070
protected Map<String, Object> getConfiguration(
7171
FilterableRequestSpecification requestSpec, FilterContext context) {
7272
Map<String, Object> configuration = new HashMap<>(
73-
context.<Map<String, Object>>getValue(CONTEXT_KEY_CONFIGURATION));
73+
getRequiredConfiguration(context));
7474
configuration.put(RestDocumentationContext.class.getName(),
7575
context.<RestDocumentationContext>getValue(
7676
RestDocumentationContext.class.getName()));
@@ -105,4 +105,13 @@ protected Map<String, Object> getConfiguration(
105105
};
106106
}
107107

108+
private static Map<String, Object> getRequiredConfiguration(FilterContext context) {
109+
Map<String, Object> configuration = context.getValue(CONTEXT_KEY_CONFIGURATION);
110+
Assert.state(configuration != null,
111+
() -> String.format("There is no REST Docs configuration. Looks like "
112+
+ "'%s' was not invoked. Please check your configuration.",
113+
RestDocumentationFilter.class.getName()));
114+
return configuration;
115+
}
116+
108117
}

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

+23
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;
@@ -432,6 +433,28 @@ public void customSnippetTemplate() throws Exception {
432433
.hasContent("Custom curl request");
433434
}
434435

436+
@Test
437+
public void exceptionShouldBeThrownWhenCallDocumentRequestSpecificationNotConfigured() {
438+
assertThatThrownBy(() -> given().port(tomcat.getPort()).filter(
439+
document("default"))
440+
.get("/")).isInstanceOf(IllegalStateException.class).hasMessageContaining(
441+
"There is no REST Docs configuration. Looks like 'org.springframework."
442+
+ "restdocs.restassured3.RestDocumentationFilter' was not invoked."
443+
+ " Please check your configuration.");
444+
}
445+
446+
@Test
447+
public void exceptionShouldBeThrownWhenCallDocumentSnippetsRequestSpecificationNotConfigured() {
448+
RestDocumentationFilter documentation = document("{method-name}-{step}");
449+
assertThatThrownBy(() -> given().port(tomcat.getPort())
450+
.filter(documentation.document(
451+
responseHeaders(headerWithName("a").description("one"))))
452+
.get("/")).isInstanceOf(IllegalStateException.class).hasMessageContaining(
453+
"There is no REST Docs configuration. Looks like 'org.springframework."
454+
+ "restdocs.restassured3.RestDocumentationFilter' was not invoked."
455+
+ " Please check your configuration.");
456+
}
457+
435458
private void assertExpectedSnippetFilesExist(File directory, String... snippets) {
436459
for (String snippet : snippets) {
437460
assertThat(new File(directory, snippet)).isFile();

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

+13-8
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.test.web.reactive.server.WebTestClient.BodyContentSpec;
3131
import org.springframework.test.web.reactive.server.WebTestClient.BodySpec;
3232
import org.springframework.test.web.reactive.server.WebTestClient.Builder;
33+
import org.springframework.util.Assert;
3334
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
3435

3536
/**
@@ -77,7 +78,7 @@ public static <T extends ExchangeResult> Consumer<T> document(String identifier,
7778
Snippet... snippets) {
7879
return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER,
7980
RESPONSE_CONVERTER, snippets).handle(result, result,
80-
retrieveConfiguration(result));
81+
getRequiredConfiguration(result));
8182
}
8283

8384
/**
@@ -95,7 +96,7 @@ public static <T extends ExchangeResult> Consumer<T> document(String identifier,
9596
OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) {
9697
return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER,
9798
RESPONSE_CONVERTER, requestPreprocessor, snippets).handle(result, result,
98-
retrieveConfiguration(result));
99+
getRequiredConfiguration(result));
99100
}
100101

101102
/**
@@ -113,7 +114,7 @@ public static <T extends ExchangeResult> Consumer<T> document(String identifier,
113114
OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) {
114115
return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER,
115116
RESPONSE_CONVERTER, responsePreprocessor, snippets).handle(result, result,
116-
retrieveConfiguration(result));
117+
getRequiredConfiguration(result));
117118
}
118119

119120
/**
@@ -134,13 +135,17 @@ public static <T extends ExchangeResult> Consumer<T> document(String identifier,
134135
OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) {
135136
return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER,
136137
RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets)
137-
.handle(result, result, retrieveConfiguration(result));
138+
.handle(result, result, getRequiredConfiguration(result));
138139
}
139140

140-
private static Map<String, Object> retrieveConfiguration(ExchangeResult result) {
141-
Map<String, Object> configuration = new HashMap<>(
142-
WebTestClientRestDocumentationConfigurer
143-
.retrieveConfiguration(result.getRequestHeaders()));
141+
private static Map<String, Object> getRequiredConfiguration(ExchangeResult result) {
142+
Map<String, Object> config = WebTestClientRestDocumentationConfigurer
143+
.retrieveConfiguration(result.getRequestHeaders());
144+
Assert.state(config != null, () -> String.format(
145+
"There is no REST Docs configuration. Looks like '%s' "
146+
+ "was not invoked or configuration has already been removed. Please check your configuration.",
147+
WebTestClientRestDocumentationConfigurer.class.getName()));
148+
Map<String, Object> configuration = new HashMap<>(config);
144149
configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE,
145150
result.getUriTemplate());
146151
return configuration;

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

+15
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;
@@ -199,6 +201,19 @@ public void httpieSnippetWithCookies() throws Exception {
199201
+ " 'Cookie:cookieName=cookieVal'"))));
200202
}
201203

204+
@Test
205+
public void illegalStateExceptionShouldBeThrownWhenCallDocumentWebClientNotConfigured() {
206+
assertThatThrownBy(() -> this.webTestClient
207+
.mutateWith((builder, httpHandlerBuilder, connector) -> builder
208+
.filters(List::clear).build())
209+
.get().uri("/").exchange().expectBody()
210+
.consumeWith(document("default-snippets")))
211+
.isInstanceOf(IllegalStateException.class).hasMessageContaining(
212+
"There is no REST Docs configuration. Looks like "
213+
+ "'org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer' "
214+
+ "was not invoked or configuration has already been removed. Please check your configuration.");
215+
}
216+
202217
private void assertExpectedSnippetFilesExist(File directory, String... snippets) {
203218
Set<File> actual = new HashSet<>(Arrays.asList(directory.listFiles()));
204219
Set<File> expected = Stream.of(snippets)

0 commit comments

Comments
 (0)