diff --git a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java index 7f48b2ed3..c90d6d713 100644 --- a/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java +++ b/spring-restdocs-mockmvc/src/main/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2019 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. @@ -49,10 +49,8 @@ public class RestDocumentationResultHandler implements ResultHandler { @Override public void handle(MvcResult result) throws Exception { - @SuppressWarnings("unchecked") - Map configuration = (Map) result.getRequest() - .getAttribute(ATTRIBUTE_NAME_CONFIGURATION); - this.delegate.handle(result.getRequest(), result.getResponse(), configuration); + this.delegate.handle(result.getRequest(), result.getResponse(), + getRequiredConfiguration(result)); } /** @@ -75,10 +73,8 @@ public RestDocumentationResultHandler document(Snippet... snippets) { @Override public void handle(MvcResult result) throws Exception { - @SuppressWarnings("unchecked") Map configuration = new HashMap<>( - (Map) result.getRequest() - .getAttribute(ATTRIBUTE_NAME_CONFIGURATION)); + getRequiredConfiguration(result)); configuration.remove( RestDocumentationGenerator.ATTRIBUTE_NAME_DEFAULT_SNIPPETS); getDelegate().handle(result.getRequest(), result.getResponse(), @@ -96,4 +92,15 @@ protected final RestDocumentationGenerator getRequiredConfiguration(MvcResult result) { + @SuppressWarnings("unchecked") + Map configuration = (Map) result.getRequest() + .getAttribute(ATTRIBUTE_NAME_CONFIGURATION); + Assert.state(configuration != null, + () -> String.format("There is no REST Docs configuration. Looks like " + + "'%s' was not invoked. Please check your configuration.", + MockMvcRestDocumentationConfigurer.class.getName())); + return configuration; + } + } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java index c0fc54cf5..88b606c25 100644 --- a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/MockMvcRestDocumentationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2019 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. @@ -69,6 +69,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; @@ -594,6 +595,36 @@ public void customContextPath() throws Exception { + " -H 'Accept: application/json'")))); } + @Test + public void exceptionShouldBeThrownWhenCallDocumentMockMvcNotConfigured() { + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + assertThatThrownBy( + () -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) + .andDo(document("basic"))) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining(missingConfigurationMessage()); + + } + + @Test + public void exceptionShouldBeThrownWhenCallDocumentSnippetsMockMvcNotConfigured() { + RestDocumentationResultHandler documentation = document("{method-name}-{step}"); + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); + assertThatThrownBy( + () -> mockMvc.perform(get("/").accept(MediaType.APPLICATION_JSON)) + .andDo(documentation.document( + responseHeaders(headerWithName("a").description("one"))))) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining( + missingConfigurationMessage()); + } + + private String missingConfigurationMessage() { + return "There is no REST Docs configuration. Looks like " + + "'org.springframework.restdocs.mockmvc.MockMvcRestDocumentationConfigurer' " + + "was not invoked. Please check your configuration."; + } + @Test public void multiPart() throws Exception { MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.context) diff --git a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java index 58735d695..2d2d73b24 100644 --- a/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java +++ b/spring-restdocs-restassured/src/main/java/org/springframework/restdocs/restassured3/RestDocumentationFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2019 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. @@ -70,7 +70,7 @@ public final Response filter(FilterableRequestSpecification requestSpec, protected Map getConfiguration( FilterableRequestSpecification requestSpec, FilterContext context) { Map configuration = new HashMap<>( - context.>getValue(CONTEXT_KEY_CONFIGURATION)); + getRequiredConfiguration(context)); configuration.put(RestDocumentationContext.class.getName(), context.getValue( RestDocumentationContext.class.getName())); @@ -105,4 +105,13 @@ protected Map getConfiguration( }; } + private static Map getRequiredConfiguration(FilterContext context) { + Map configuration = context.getValue(CONTEXT_KEY_CONFIGURATION); + Assert.state(configuration != null, + () -> String.format("There is no REST Docs configuration. Looks like " + + "'%s' was not invoked. Please check your configuration.", + RestDocumentationFilter.class.getName())); + return configuration; + } + } diff --git a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java index 19beb455b..fb5b24f3d 100644 --- a/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java +++ b/spring-restdocs-restassured/src/test/java/org/springframework/restdocs/restassured3/RestAssuredRestDocumentationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2019 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. @@ -47,6 +47,7 @@ import static io.restassured.RestAssured.given; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName; import static org.springframework.restdocs.headers.HeaderDocumentation.responseHeaders; @@ -432,6 +433,31 @@ public void customSnippetTemplate() throws Exception { .hasContent("Custom curl request"); } + @Test + public void exceptionShouldBeThrownWhenCallDocumentRequestSpecificationNotConfigured() { + assertThatThrownBy( + () -> given().port(tomcat.getPort()).filter(document("default")).get("/")) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining(messingConfigurationMessage()); + } + + @Test + public void exceptionShouldBeThrownWhenCallDocumentSnippetsRequestSpecificationNotConfigured() { + RestDocumentationFilter documentation = document("{method-name}-{step}"); + assertThatThrownBy(() -> given().port(tomcat.getPort()) + .filter(documentation.document( + responseHeaders(headerWithName("a").description("one")))) + .get("/")).isInstanceOf(IllegalStateException.class) + .hasMessageContaining(messingConfigurationMessage()); + } + + private String messingConfigurationMessage() { + return "There is no REST Docs configuration. Looks like 'org.springframework." + + "restdocs.restassured3.RestDocumentationFilter' was not invoked." + + " Please check your configuration."; + + } + private void assertExpectedSnippetFilesExist(File directory, String... snippets) { for (String snippet : snippets) { assertThat(new File(directory, snippet)).isFile(); diff --git a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java index cb7613c72..c36b9e803 100644 --- a/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java +++ b/spring-restdocs-webtestclient/src/main/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2019 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,6 +30,7 @@ import org.springframework.test.web.reactive.server.WebTestClient.BodyContentSpec; import org.springframework.test.web.reactive.server.WebTestClient.BodySpec; import org.springframework.test.web.reactive.server.WebTestClient.Builder; +import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; /** @@ -77,7 +78,7 @@ public static Consumer document(String identifier, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, snippets).handle(result, result, - retrieveConfiguration(result)); + getRequiredConfiguration(result)); } /** @@ -95,7 +96,7 @@ public static Consumer document(String identifier, OperationRequestPreprocessor requestPreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, snippets).handle(result, result, - retrieveConfiguration(result)); + getRequiredConfiguration(result)); } /** @@ -113,7 +114,7 @@ public static Consumer document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, responsePreprocessor, snippets).handle(result, result, - retrieveConfiguration(result)); + getRequiredConfiguration(result)); } /** @@ -134,13 +135,17 @@ public static Consumer document(String identifier, OperationResponsePreprocessor responsePreprocessor, Snippet... snippets) { return (result) -> new RestDocumentationGenerator<>(identifier, REQUEST_CONVERTER, RESPONSE_CONVERTER, requestPreprocessor, responsePreprocessor, snippets) - .handle(result, result, retrieveConfiguration(result)); + .handle(result, result, getRequiredConfiguration(result)); } - private static Map retrieveConfiguration(ExchangeResult result) { - Map configuration = new HashMap<>( - WebTestClientRestDocumentationConfigurer - .retrieveConfiguration(result.getRequestHeaders())); + private static Map getRequiredConfiguration(ExchangeResult result) { + Map config = WebTestClientRestDocumentationConfigurer + .retrieveConfiguration(result.getRequestHeaders()); + Assert.state(config != null, () -> String.format( + "There is no REST Docs configuration. Looks like '%s' " + + "was not invoked or configuration has already been removed. Please check your configuration.", + WebTestClientRestDocumentationConfigurer.class.getName())); + Map configuration = new HashMap<>(config); configuration.put(RestDocumentationGenerator.ATTRIBUTE_NAME_URL_TEMPLATE, result.getUriTemplate()); return configuration; diff --git a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java index 74996b1b8..1c6aa0b3c 100644 --- a/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java +++ b/spring-restdocs-webtestclient/src/test/java/org/springframework/restdocs/webtestclient/WebTestClientRestDocumentationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2018 the original author or authors. + * Copyright 2014-2019 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,6 +23,7 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -58,6 +59,7 @@ import org.springframework.web.reactive.function.server.ServerResponse; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName; import static org.springframework.restdocs.request.RequestDocumentation.partWithName; @@ -199,6 +201,23 @@ public void httpieSnippetWithCookies() throws Exception { + " 'Cookie:cookieName=cookieVal'")))); } + @Test + public void illegalStateExceptionShouldBeThrownWhenCallDocumentWebClientNotConfigured() { + assertThatThrownBy(() -> this.webTestClient + .mutateWith((builder, httpHandlerBuilder, connector) -> builder + .filters(List::clear).build()) + .get().uri("/").exchange().expectBody() + .consumeWith(document("default-snippets"))) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining(missingConfiguration()); + } + + private String missingConfiguration() { + return "There is no REST Docs configuration. Looks like " + + "'org.springframework.restdocs.webtestclient.WebTestClientRestDocumentationConfigurer' " + + "was not invoked or configuration has already been removed. Please check your configuration."; + } + private void assertExpectedSnippetFilesExist(File directory, String... snippets) { Set actual = new HashSet<>(Arrays.asList(directory.listFiles())); Set expected = Stream.of(snippets)