diff --git a/test/src/main/java/org/springframework/security/test/context/support/WithSecurityContextTestExecutionListener.java b/test/src/main/java/org/springframework/security/test/context/support/WithSecurityContextTestExecutionListener.java index 4f4ebb44aa..8c6a02417b 100644 --- a/test/src/main/java/org/springframework/security/test/context/support/WithSecurityContextTestExecutionListener.java +++ b/test/src/main/java/org/springframework/security/test/context/support/WithSecurityContextTestExecutionListener.java @@ -17,7 +17,9 @@ package org.springframework.security.test.context.support; import java.lang.annotation.Annotation; +import org.springframework.beans.BeanUtils; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.StaticApplicationContext; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.Order; import org.springframework.security.core.context.SecurityContext; @@ -28,7 +30,10 @@ import org.springframework.test.context.TestContext; import org.springframework.test.context.TestExecutionListener; import org.springframework.test.context.support.AbstractTestExecutionListener; import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.util.ClassUtils; +import org.springframework.util.ReflectionUtils; /** * A {@link TestExecutionListener} that will find annotations that are annotated with @@ -45,6 +50,7 @@ import org.springframework.test.web.servlet.MockMvc; public class WithSecurityContextTestExecutionListener extends AbstractTestExecutionListener { + /** * Sets up the {@link SecurityContext} for each test method. First the specific method * is inspected for a {@link WithSecurityContext} or {@link Annotation} that has @@ -55,12 +61,11 @@ public class WithSecurityContextTestExecutionListener extends public void beforeTestMethod(TestContext testContext) throws Exception { Annotation[] methodAnnotations = AnnotationUtils.getAnnotations(testContext .getTestMethod()); - ApplicationContext context = testContext.getApplicationContext(); SecurityContext securityContext = createSecurityContext(methodAnnotations, - context); + testContext); if (securityContext == null) { Annotation[] classAnnotations = testContext.getTestClass().getAnnotations(); - securityContext = createSecurityContext(classAnnotations, context); + securityContext = createSecurityContext(classAnnotations, testContext); } if (securityContext != null) { TestSecurityContextHolder.setContext(securityContext); @@ -69,7 +74,7 @@ public class WithSecurityContextTestExecutionListener extends @SuppressWarnings({ "rawtypes", "unchecked" }) private SecurityContext createSecurityContext(Annotation[] annotations, - ApplicationContext context) { + TestContext context) { for (Annotation a : annotations) { WithSecurityContext withUser = AnnotationUtils.findAnnotation( a.annotationType(), WithSecurityContext.class); @@ -88,11 +93,14 @@ public class WithSecurityContextTestExecutionListener extends } private WithSecurityContextFactory createFactory( - WithSecurityContext withUser, ApplicationContext context) { + WithSecurityContext withUser, TestContext testContext) { Class> clazz = withUser .factory(); try { - return context.getAutowireCapableBeanFactory().createBean(clazz); + return testContext.getApplicationContext().getAutowireCapableBeanFactory().createBean(clazz); + } + catch (IllegalStateException e) { + return BeanUtils.instantiateClass(clazz); } catch (Exception e) { throw new RuntimeException(e); diff --git a/test/src/test/java/org/springframework/security/test/context/support/WithSecurityContextTestExcecutionListenerTests.java b/test/src/test/java/org/springframework/security/test/context/support/WithSecurityContextTestExcecutionListenerTests.java index a6590e9110..c22de98c42 100644 --- a/test/src/test/java/org/springframework/security/test/context/support/WithSecurityContextTestExcecutionListenerTests.java +++ b/test/src/test/java/org/springframework/security/test/context/support/WithSecurityContextTestExcecutionListenerTests.java @@ -15,6 +15,8 @@ */ package org.springframework.security.test.context.support; +import static org.fest.assertions.Assertions.*; + import static org.mockito.Mockito.when; import org.junit.After; @@ -27,6 +29,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.security.test.context.TestSecurityContextHolder; +import org.springframework.test.AssertThrows; import org.springframework.test.context.TestContext; import org.springframework.util.ReflectionUtils; @@ -65,9 +68,28 @@ public class WithSecurityContextTestExcecutionListenerTests { listener.beforeTestMethod(testContext); } + @Test + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void beforeTestMethodNoApplicationContext() throws Exception { + Class testClass = FakeTest.class; + when(testContext.getApplicationContext()).thenThrow(new IllegalStateException()); + when(testContext.getTestClass()).thenReturn(testClass); + when(testContext.getTestMethod()).thenReturn( + ReflectionUtils.findMethod(testClass, "testWithMockUser")); + + listener.beforeTestMethod(testContext); + + assertThat(TestSecurityContextHolder.getContext().getAuthentication().getName()).isEqualTo("user"); + } + static class FakeTest { public void testNoAnnotation() { } + + @WithMockUser + public void testWithMockUser() { + + } } @Configuration