2
0
Эх сурвалжийг харах

SEC-3041: Fix WithSecurityContextTestExecutionListener w/ no ApplicationContext

Rob Winch 10 жил өмнө
parent
commit
4cafd575c0

+ 14 - 6
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 java.lang.annotation.Annotation;
 
 
+import org.springframework.beans.BeanUtils;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.StaticApplicationContext;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.core.annotation.AnnotationUtils;
 import org.springframework.core.annotation.Order;
 import org.springframework.core.annotation.Order;
 import org.springframework.security.core.context.SecurityContext;
 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.TestExecutionListener;
 import org.springframework.test.context.support.AbstractTestExecutionListener;
 import org.springframework.test.context.support.AbstractTestExecutionListener;
 import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
 import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
+import org.springframework.test.util.ReflectionTestUtils;
 import org.springframework.test.web.servlet.MockMvc;
 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
  * 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
 public class WithSecurityContextTestExecutionListener extends
 		AbstractTestExecutionListener {
 		AbstractTestExecutionListener {
 
 
+
 	/**
 	/**
 	 * Sets up the {@link SecurityContext} for each test method. First the specific method
 	 * Sets up the {@link SecurityContext} for each test method. First the specific method
 	 * is inspected for a {@link WithSecurityContext} or {@link Annotation} that has
 	 * 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 {
 	public void beforeTestMethod(TestContext testContext) throws Exception {
 		Annotation[] methodAnnotations = AnnotationUtils.getAnnotations(testContext
 		Annotation[] methodAnnotations = AnnotationUtils.getAnnotations(testContext
 				.getTestMethod());
 				.getTestMethod());
-		ApplicationContext context = testContext.getApplicationContext();
 		SecurityContext securityContext = createSecurityContext(methodAnnotations,
 		SecurityContext securityContext = createSecurityContext(methodAnnotations,
-				context);
+				testContext);
 		if (securityContext == null) {
 		if (securityContext == null) {
 			Annotation[] classAnnotations = testContext.getTestClass().getAnnotations();
 			Annotation[] classAnnotations = testContext.getTestClass().getAnnotations();
-			securityContext = createSecurityContext(classAnnotations, context);
+			securityContext = createSecurityContext(classAnnotations, testContext);
 		}
 		}
 		if (securityContext != null) {
 		if (securityContext != null) {
 			TestSecurityContextHolder.setContext(securityContext);
 			TestSecurityContextHolder.setContext(securityContext);
@@ -69,7 +74,7 @@ public class WithSecurityContextTestExecutionListener extends
 
 
 	@SuppressWarnings({ "rawtypes", "unchecked" })
 	@SuppressWarnings({ "rawtypes", "unchecked" })
 	private SecurityContext createSecurityContext(Annotation[] annotations,
 	private SecurityContext createSecurityContext(Annotation[] annotations,
-			ApplicationContext context) {
+			TestContext context) {
 		for (Annotation a : annotations) {
 		for (Annotation a : annotations) {
 			WithSecurityContext withUser = AnnotationUtils.findAnnotation(
 			WithSecurityContext withUser = AnnotationUtils.findAnnotation(
 					a.annotationType(), WithSecurityContext.class);
 					a.annotationType(), WithSecurityContext.class);
@@ -88,11 +93,14 @@ public class WithSecurityContextTestExecutionListener extends
 	}
 	}
 
 
 	private WithSecurityContextFactory<? extends Annotation> createFactory(
 	private WithSecurityContextFactory<? extends Annotation> createFactory(
-			WithSecurityContext withUser, ApplicationContext context) {
+			WithSecurityContext withUser, TestContext testContext) {
 		Class<? extends WithSecurityContextFactory<? extends Annotation>> clazz = withUser
 		Class<? extends WithSecurityContextFactory<? extends Annotation>> clazz = withUser
 				.factory();
 				.factory();
 		try {
 		try {
-			return context.getAutowireCapableBeanFactory().createBean(clazz);
+			return testContext.getApplicationContext().getAutowireCapableBeanFactory().createBean(clazz);
+		}
+		catch (IllegalStateException e) {
+			return BeanUtils.instantiateClass(clazz);
 		}
 		}
 		catch (Exception e) {
 		catch (Exception e) {
 			throw new RuntimeException(e);
 			throw new RuntimeException(e);

+ 22 - 0
test/src/test/java/org/springframework/security/test/context/support/WithSecurityContextTestExcecutionListenerTests.java

@@ -15,6 +15,8 @@
  */
  */
 package org.springframework.security.test.context.support;
 package org.springframework.security.test.context.support;
 
 
+import static org.fest.assertions.Assertions.*;
+
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.when;
 
 
 import org.junit.After;
 import org.junit.After;
@@ -27,6 +29,7 @@ import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.test.context.TestSecurityContextHolder;
 import org.springframework.security.test.context.TestSecurityContextHolder;
+import org.springframework.test.AssertThrows;
 import org.springframework.test.context.TestContext;
 import org.springframework.test.context.TestContext;
 import org.springframework.util.ReflectionUtils;
 import org.springframework.util.ReflectionUtils;
 
 
@@ -65,9 +68,28 @@ public class WithSecurityContextTestExcecutionListenerTests {
 		listener.beforeTestMethod(testContext);
 		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 {
 	static class FakeTest {
 		public void testNoAnnotation() {
 		public void testNoAnnotation() {
 		}
 		}
+
+		@WithMockUser
+		public void testWithMockUser() {
+
+		}
 	}
 	}
 
 
 	@Configuration
 	@Configuration