From bb590db39625c63157a929f06e9b255349300c14 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 9 Mar 2016 23:33:45 -0800 Subject: [PATCH 1/2] Support servlet listener activate attribute Add a ServletTestExecutionListener.ACTIVATE_LISTENER attribute which can be set on the TestContext to trigger activation of the listener even if a `@WebAppConfiguration` is not present. Issue: SPR-14035 --- .../web/ServletTestExecutionListener.java | 19 +++++++++++++++---- .../ServletTestExecutionListenerTests.java | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java index a1bdb5a2eb..400da364ac 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-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. @@ -98,6 +98,16 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener public static final String CREATED_BY_THE_TESTCONTEXT_FRAMEWORK = Conventions.getQualifiedAttributeName( ServletTestExecutionListener.class, "createdByTheTestContextFramework"); + /** + * Attribute name for a {@link TestContext} attribute which indicates that + * that the {@link ServletTestExecutionListener} should be activated. When + * not specified activation occurs when the {@linkplain TestContext#getTestClass() + * test class} is annotated with {@link WebAppConfiguration @WebAppConfiguration}. + * @since 4.4 + */ + public static final String ACTIVATE_LISTENER = Conventions.getQualifiedAttributeName( + ServletTestExecutionListener.class, "webApplicationConfiguration"); + private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class); @@ -167,8 +177,9 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener testContext.removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); } - private boolean notAnnotatedWithWebAppConfiguration(TestContext testContext) { - return AnnotationUtils.findAnnotation(testContext.getTestClass(), WebAppConfiguration.class) == null; + private boolean isActivated(TestContext testContext) { + return (Boolean.TRUE.equals(testContext.getAttribute(ACTIVATE_LISTENER)) + || AnnotationUtils.findAnnotation(testContext.getTestClass(), WebAppConfiguration.class) != null); } private boolean alreadyPopulatedRequestContextHolder(TestContext testContext) { @@ -176,7 +187,7 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener } private void setUpRequestContextIfNecessary(TestContext testContext) { - if (notAnnotatedWithWebAppConfiguration(testContext) || alreadyPopulatedRequestContextHolder(testContext)) { + if (!isActivated(testContext) || alreadyPopulatedRequestContextHolder(testContext)) { return; } diff --git a/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java b/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java index 0353a87046..1d0179ec76 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -173,6 +173,18 @@ public class ServletTestExecutionListenerTests { assertWebAppConfigTestCase(); } + @Test + public void activateAttributeAppConfigTestCaseWithoutExistingRequestAttributes() throws Exception { + BDDMockito.> given(testContext.getTestClass()).willReturn(NoAtWebAppConfigWebTestCase.class); + given(testContext.getAttribute(ServletTestExecutionListener.ACTIVATE_LISTENER)).willReturn(true); + + RequestContextHolder.resetRequestAttributes(); + listener.beforeTestClass(testContext); + assertAttributesNotAvailable(); + + assertWebAppConfigTestCase(); + } + private void assertWebAppConfigTestCase() throws Exception { listener.prepareTestInstance(testContext); assertAttributeDoesNotExist(); @@ -200,4 +212,7 @@ public class ServletTestExecutionListenerTests { static class AtWebAppConfigWebTestCase { } + static class NoAtWebAppConfigWebTestCase { + } + } From 51eccf552f5771c17b726085d9df3b53842f292a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 10 Mar 2016 17:20:02 +0100 Subject: [PATCH 2/2] Polish ServletTestExecutionListener[Tests] --- .../web/ServletTestExecutionListener.java | 13 ++- .../ServletTestExecutionListenerTests.java | 97 ++++++++++--------- 2 files changed, 60 insertions(+), 50 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java index 400da364ac..9585552bc3 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/ServletTestExecutionListener.java @@ -61,6 +61,7 @@ import org.springframework.web.context.request.ServletWebRequest; * See the Javadoc for individual methods in this class for details. * * @author Sam Brannen + * @author Phillip Webb * @since 3.2 */ public class ServletTestExecutionListener extends AbstractTestExecutionListener { @@ -99,14 +100,16 @@ public class ServletTestExecutionListener extends AbstractTestExecutionListener ServletTestExecutionListener.class, "createdByTheTestContextFramework"); /** - * Attribute name for a {@link TestContext} attribute which indicates that - * that the {@link ServletTestExecutionListener} should be activated. When - * not specified activation occurs when the {@linkplain TestContext#getTestClass() + * Attribute name for a {@link TestContext} attribute which indicates that that + * the {@code ServletTestExecutionListener} should be activated. When not set to + * {@code true}, activation occurs when the {@linkplain TestContext#getTestClass() * test class} is annotated with {@link WebAppConfiguration @WebAppConfiguration}. - * @since 4.4 + * + *

Permissible values include {@link Boolean#TRUE} and {@link Boolean#FALSE}. + * @since 4.3 */ public static final String ACTIVATE_LISTENER = Conventions.getQualifiedAttributeName( - ServletTestExecutionListener.class, "webApplicationConfiguration"); + ServletTestExecutionListener.class, "activateListener"); private static final Log logger = LogFactory.getLog(ServletTestExecutionListener.class); diff --git a/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java b/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java index 1d0179ec76..5ca2113f27 100644 --- a/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/web/ServletTestExecutionListenerTests.java @@ -38,11 +38,12 @@ import static org.springframework.test.context.web.ServletTestExecutionListener. * Unit tests for {@link ServletTestExecutionListener}. * * @author Sam Brannen + * @author Phillip Webb * @since 3.2.6 */ public class ServletTestExecutionListenerTests { - private static final String SET_UP_OUTSIDE_OF_STEL = "SET_UP_OUTSIDE_OF_STEL"; + private static final String SET_UP_OUTSIDE_OF_STEL = "setUpOutsideOfStel"; private final WebApplicationContext wac = mock(WebApplicationContext.class); private final MockServletContext mockServletContext = new MockServletContext(); @@ -50,30 +51,6 @@ public class ServletTestExecutionListenerTests { private final ServletTestExecutionListener listener = new ServletTestExecutionListener(); - private void assertAttributesAvailable() { - assertNotNull("request attributes should be available", RequestContextHolder.getRequestAttributes()); - } - - private void assertAttributesNotAvailable() { - assertNull("request attributes should not be available", RequestContextHolder.getRequestAttributes()); - } - - private void assertAttributeExists() { - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - assertNotNull("request attributes should exist", requestAttributes); - Object setUpOutsideOfStel = requestAttributes.getAttribute(SET_UP_OUTSIDE_OF_STEL, - RequestAttributes.SCOPE_REQUEST); - assertNotNull(SET_UP_OUTSIDE_OF_STEL + " should exist as a request attribute", setUpOutsideOfStel); - } - - private void assertAttributeDoesNotExist() { - RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); - assertNotNull("request attributes should exist", requestAttributes); - Object setUpOutsideOfStel = requestAttributes.getAttribute(SET_UP_OUTSIDE_OF_STEL, - RequestAttributes.SCOPE_REQUEST); - assertNull(SET_UP_OUTSIDE_OF_STEL + " should NOT exist as a request attribute", setUpOutsideOfStel); - } - @Before public void setUp() { given(wac.getServletContext()).willReturn(mockServletContext); @@ -86,7 +63,7 @@ public class ServletTestExecutionListenerTests { request.setAttribute(SET_UP_OUTSIDE_OF_STEL, "true"); RequestContextHolder.setRequestAttributes(servletWebRequest); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); } @Test @@ -95,16 +72,16 @@ public class ServletTestExecutionListenerTests { given(testContext.getApplicationContext()).willReturn(mock(ApplicationContext.class)); listener.beforeTestClass(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); listener.prepareTestInstance(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); listener.beforeTestMethod(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); listener.afterTestMethod(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); } @Test @@ -112,22 +89,22 @@ public class ServletTestExecutionListenerTests { BDDMockito.> given(testContext.getTestClass()).willReturn(LegacyWebTestCase.class); RequestContextHolder.resetRequestAttributes(); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); listener.beforeTestClass(testContext); listener.prepareTestInstance(testContext); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); verify(testContext, times(0)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); given(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).willReturn(null); listener.beforeTestMethod(testContext); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); verify(testContext, times(0)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); listener.afterTestMethod(testContext); verify(testContext, times(1)).removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); } @Test @@ -135,21 +112,21 @@ public class ServletTestExecutionListenerTests { BDDMockito.> given(testContext.getTestClass()).willReturn(LegacyWebTestCase.class); listener.beforeTestClass(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); listener.prepareTestInstance(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); verify(testContext, times(0)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); given(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).willReturn(null); listener.beforeTestMethod(testContext); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); verify(testContext, times(0)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); given(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).willReturn(null); listener.afterTestMethod(testContext); verify(testContext, times(1)).removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); - assertAttributeExists(); + assertSetUpOutsideOfStelAttributeExists(); } @Test @@ -158,7 +135,7 @@ public class ServletTestExecutionListenerTests { RequestContextHolder.resetRequestAttributes(); listener.beforeTestClass(testContext); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); assertWebAppConfigTestCase(); } @@ -168,40 +145,70 @@ public class ServletTestExecutionListenerTests { BDDMockito.> given(testContext.getTestClass()).willReturn(AtWebAppConfigWebTestCase.class); listener.beforeTestClass(testContext); - assertAttributesAvailable(); + assertRequestAttributesExist(); assertWebAppConfigTestCase(); } + /** + * @since 4.3 + */ @Test - public void activateAttributeAppConfigTestCaseWithoutExistingRequestAttributes() throws Exception { + public void activateListenerWithoutExistingRequestAttributes() throws Exception { BDDMockito.> given(testContext.getTestClass()).willReturn(NoAtWebAppConfigWebTestCase.class); given(testContext.getAttribute(ServletTestExecutionListener.ACTIVATE_LISTENER)).willReturn(true); RequestContextHolder.resetRequestAttributes(); listener.beforeTestClass(testContext); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); assertWebAppConfigTestCase(); } + + private RequestAttributes assertRequestAttributesExist() { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); + assertNotNull("request attributes should exist", requestAttributes); + return requestAttributes; + } + + private void assertRequestAttributesDoNotExist() { + assertNull("request attributes should not not exist", RequestContextHolder.getRequestAttributes()); + } + + private void assertSetUpOutsideOfStelAttributeExists() { + RequestAttributes requestAttributes = assertRequestAttributesExist(); + Object setUpOutsideOfStel = requestAttributes.getAttribute(SET_UP_OUTSIDE_OF_STEL, + RequestAttributes.SCOPE_REQUEST); + assertNotNull(SET_UP_OUTSIDE_OF_STEL + " should exist as a request attribute", setUpOutsideOfStel); + } + + private void assertSetUpOutsideOfStelAttributeDoesNotExist() { + RequestAttributes requestAttributes = assertRequestAttributesExist(); + Object setUpOutsideOfStel = requestAttributes.getAttribute(SET_UP_OUTSIDE_OF_STEL, + RequestAttributes.SCOPE_REQUEST); + assertNull(SET_UP_OUTSIDE_OF_STEL + " should NOT exist as a request attribute", setUpOutsideOfStel); + } + private void assertWebAppConfigTestCase() throws Exception { listener.prepareTestInstance(testContext); - assertAttributeDoesNotExist(); + assertRequestAttributesExist(); + assertSetUpOutsideOfStelAttributeDoesNotExist(); verify(testContext, times(1)).setAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); verify(testContext, times(1)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); given(testContext.getAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).willReturn(Boolean.TRUE); given(testContext.getAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE)).willReturn(Boolean.TRUE); listener.beforeTestMethod(testContext); - assertAttributeDoesNotExist(); + assertRequestAttributesExist(); + assertSetUpOutsideOfStelAttributeDoesNotExist(); verify(testContext, times(1)).setAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); verify(testContext, times(1)).setAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE, Boolean.TRUE); listener.afterTestMethod(testContext); verify(testContext).removeAttribute(POPULATED_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); verify(testContext).removeAttribute(RESET_REQUEST_CONTEXT_HOLDER_ATTRIBUTE); - assertAttributesNotAvailable(); + assertRequestAttributesDoNotExist(); }