From ad549ae7c0301ea39c6e67dcbd734e943e4f90cc Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 24 May 2016 11:30:49 +0100 Subject: [PATCH] Ensure that additional snippets are only called once Previously, when additional snippets were added to a RestDocumentationResultHandler, those snippets would then be called for every subsequent call to handle(MvcResult). This is problematic as the snippets and their configuration are specific to a particular MvcResult that is being documented. This commit updates RestDocumentationResultHandler so that it clears its additional snippets each time handle(MvcResult) is called. Closes gh-243 --- .../RestDocumentationResultHandler.java | 7 +- .../RestDocumentationResultHandlerTests.java | 64 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java 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 962f12b4..1969e5e9 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 @@ -44,6 +44,8 @@ import static org.springframework.restdocs.mockmvc.IterableEnumeration.iterable; */ public class RestDocumentationResultHandler implements ResultHandler { + private final List additionalSnippets; + private final String identifier; private final OperationRequestPreprocessor requestPreprocessor; @@ -80,6 +82,7 @@ public class RestDocumentationResultHandler implements ResultHandler { this.requestPreprocessor = requestPreprocessor; this.responsePreprocessor = responsePreprocessor; this.snippets = new ArrayList<>(Arrays.asList(snippets)); + this.additionalSnippets = new ArrayList<>(); } @Override @@ -110,7 +113,7 @@ public class RestDocumentationResultHandler implements ResultHandler { * @return this {@code ResultDocumentationResultHandler} */ public RestDocumentationResultHandler snippets(Snippet... snippets) { - this.snippets.addAll(Arrays.asList(snippets)); + this.additionalSnippets.addAll(Arrays.asList(snippets)); return this; } @@ -120,6 +123,8 @@ public class RestDocumentationResultHandler implements ResultHandler { (List) result.getRequest().getAttribute( "org.springframework.restdocs.mockmvc.defaultSnippets")); combinedSnippets.addAll(this.snippets); + combinedSnippets.addAll(this.additionalSnippets); + this.additionalSnippets.clear(); return combinedSnippets; } diff --git a/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java new file mode 100644 index 00000000..4c8b53de --- /dev/null +++ b/spring-restdocs-mockmvc/src/test/java/org/springframework/restdocs/mockmvc/RestDocumentationResultHandlerTests.java @@ -0,0 +1,64 @@ +/* + * Copyright 2014-2016 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 + * + * http://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.restdocs.mockmvc; + +import java.util.Arrays; + +import org.junit.Test; +import org.mockito.Matchers; + +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.restdocs.operation.Operation; +import org.springframework.restdocs.snippet.Snippet; +import org.springframework.test.web.servlet.MvcResult; + +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * Tests for {@link RestDocumentationResultHandler}. + * + * @author Andy Wilkinson + */ +public class RestDocumentationResultHandlerTests { + + @Test + public void additionalSnippetsAreOnlyCalledOnce() throws Exception { + Snippet snippet = mock(Snippet.class); + RestDocumentationResultHandler resultHandler = new RestDocumentationResultHandler( + "test", snippet); + Snippet defaultSnippet = mock(Snippet.class); + Snippet additionalSnippet = mock(Snippet.class); + resultHandler.snippets(additionalSnippet); + MvcResult result = mock(MvcResult.class); + MockHttpServletRequest request = new MockHttpServletRequest("GET", + "http://localhost"); + request.setAttribute("org.springframework.restdocs.mockmvc.defaultSnippets", + Arrays.asList(defaultSnippet)); + given(result.getRequest()).willReturn(request); + given(result.getResponse()).willReturn(new MockHttpServletResponse()); + resultHandler.handle(result); + resultHandler.handle(result); + verify(defaultSnippet, times(2)).document(Matchers.any(Operation.class)); + verify(snippet, times(2)).document(Matchers.any(Operation.class)); + verify(additionalSnippet, times(1)).document(Matchers.any(Operation.class)); + } + +}