Преглед изворни кода

Remove Powermock

Powermock does not support JUnit5 yet, so we need to remove it
to support JUnit 5. Additionally, maintaining additional libraries
adds extra work for the team.

Mockito now supports final classes and static method mocking. This
commit replaces Powermock with mockito-inline.

Closes gh-6025
Rob Winch пре 4 година
родитељ
комит
14240b2559
43 измењених фајлова са 300 додато и 286 уклоњено
  1. 0 23
      buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy
  2. 1 2
      buildSrc/src/test/resources/samples/dependencyset/build.gradle
  3. 2 8
      buildSrc/src/test/resources/samples/dependencyset/gradle/dependency-management.gradle
  4. 2 1
      config/spring-security-config.gradle
  5. 24 28
      config/src/test/java/org/springframework/security/config/SecurityNamespaceHandlerTests.java
  6. 11 13
      config/src/test/java/org/springframework/security/config/annotation/web/WebSecurityConfigurerAdapterMockitoTests.java
  7. 0 11
      config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerServlet31Tests.java
  8. 0 14
      config/src/test/java/org/springframework/security/config/http/SessionManagementConfigServlet31Tests.java
  9. 2 4
      config/src/test/java/org/springframework/security/config/http/WebConfigUtilsTests.java
  10. 2 1
      core/spring-security-core.gradle
  11. 21 19
      core/src/test/java/org/springframework/security/concurrent/AbstractDelegatingSecurityContextTestSupport.java
  12. 1 1
      core/src/test/java/org/springframework/security/concurrent/CurrentDelegatingSecurityContextExecutorServiceTests.java
  13. 1 1
      core/src/test/java/org/springframework/security/concurrent/CurrentDelegatingSecurityContextExecutorTests.java
  14. 1 1
      core/src/test/java/org/springframework/security/concurrent/CurrentDelegatingSecurityContextScheduledExecutorServiceTests.java
  15. 4 4
      core/src/test/java/org/springframework/security/concurrent/DelegatingSecurityContextSupportTests.java
  16. 1 1
      core/src/test/java/org/springframework/security/concurrent/ExplicitDelegatingSecurityContextExecutorServiceTests.java
  17. 1 1
      core/src/test/java/org/springframework/security/concurrent/ExplicitDelegatingSecurityContextExecutorTests.java
  18. 1 1
      core/src/test/java/org/springframework/security/concurrent/ExplicitDelegatingSecurityContextScheduledExecutorServiceTests.java
  19. 51 36
      core/src/test/java/org/springframework/security/core/SpringSecurityCoreVersionTests.java
  20. 115 0
      core/src/test/java/org/springframework/security/core/StaticFinalReflectionUtils.java
  21. 1 1
      core/src/test/java/org/springframework/security/scheduling/CurrentSecurityContextSchedulingTaskExecutorTests.java
  22. 1 1
      core/src/test/java/org/springframework/security/scheduling/ExplicitSecurityContextSchedulingTaskExecutorTests.java
  23. 1 1
      core/src/test/java/org/springframework/security/task/CurrentDelegatingSecurityContextAsyncTaskExecutorTests.java
  24. 1 1
      core/src/test/java/org/springframework/security/task/CurrentDelegatingSecurityContextTaskExecutorTests.java
  25. 1 1
      core/src/test/java/org/springframework/security/task/ExplicitDelegatingSecurityContextAsyncTaskExecutorTests.java
  26. 1 1
      core/src/test/java/org/springframework/security/task/ExplicitDelegatingSecurityContextTaskExecutorTests.java
  27. 1 6
      dependencies/spring-security-dependencies.gradle
  28. 1 1
      messaging/spring-security-messaging.gradle
  29. 1 1
      oauth2/oauth2-client/spring-security-oauth2-client.gradle
  30. 1 1
      oauth2/oauth2-core/spring-security-oauth2-core.gradle
  31. 1 1
      oauth2/oauth2-jose/spring-security-oauth2-jose.gradle
  32. 2 1
      test/spring-security-test.gradle
  33. 8 14
      test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsAuthenticationTests.java
  34. 8 14
      test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsSecurityContextTests.java
  35. 8 14
      test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsTestSecurityContextTests.java
  36. 8 14
      test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsUserDetailsTests.java
  37. 8 14
      test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsUserTests.java
  38. 2 1
      web/spring-security-web.gradle
  39. 0 8
      web/src/test/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServicesTests.java
  40. 0 3
      web/src/test/java/org/springframework/security/web/authentication/session/ChangeSessionIdAuthenticationStrategyTests.java
  41. 2 4
      web/src/test/java/org/springframework/security/web/debug/DebugFilterTests.java
  42. 0 6
      web/src/test/java/org/springframework/security/web/header/writers/CacheControlHeadersWriterTests.java
  43. 2 7
      web/src/test/java/org/springframework/security/web/servletapi/SecurityContextHolderAwareRequestFilterTests.java

+ 0 - 23
buildSrc/src/main/groovy/io/spring/gradle/convention/DependencySetPlugin.groovy

@@ -27,7 +27,6 @@ import org.gradle.api.plugins.JavaPlugin
  * <li>sockDependencies</li>
  * <li>seleniumDependencies</li>
  * <li>gebDependencies</li>
- * <li>powerMockDependencies</li>
  * <li>slf4jDependencies</li>
  * <li>jstlDependencies</li>
  * <li>apachedsDependencies</li>
@@ -61,28 +60,6 @@ public class DependencySetPlugin implements Plugin<Project> {
 			"org.codehaus.groovy:groovy-all"
 		]
 
-		project.ext.powerMockDependencies = [
-				"org.powermock:powermock-core",
-				"org.powermock:powermock-api-support",
-				"org.powermock:powermock-module-junit4-common",
-				"org.powermock:powermock-module-junit4",
-				project.dependencies.create("org.powermock:powermock-api-mockito") {
-					exclude group: 'org.mockito', module: 'mockito-all'
-				},
-				"org.powermock:powermock-reflect"
-		]
-
-		project.ext.powerMock2Dependencies = [
-				"org.powermock:powermock-core",
-				"org.powermock:powermock-api-support",
-				"org.powermock:powermock-module-junit4-common",
-				"org.powermock:powermock-module-junit4",
-				project.dependencies.create("org.powermock:powermock-api-mockito2") {
-					exclude group: 'org.mockito', module: 'mockito-all'
-				},
-				"org.powermock:powermock-reflect"
-		]
-
 		project.ext.slf4jDependencies = [
 			"org.slf4j:slf4j-api",
 			"org.slf4j:jcl-over-slf4j",

+ 1 - 2
buildSrc/src/test/resources/samples/dependencyset/build.gradle

@@ -12,10 +12,9 @@ repositories {
 dependencies {
 	testCompile spockDependencies
 	testCompile gebDependencies
-	testCompile powerMockDependencies
 	testCompile seleniumDependencies
 	testCompile slf4jDependencies
 	testCompile springCoreDependency
 	testCompile jstlDependencies
 	testCompile apachedsDependencies
-}
+}

+ 2 - 8
buildSrc/src/test/resources/samples/dependencyset/gradle/dependency-management.gradle

@@ -704,13 +704,7 @@ def deps = [
 	"xml-apis:xml-apis" : "1.4.01",
 	"xmlunit:xmlunit" : "1.6",
 	"xom:xom" : "1.2.5",
-	"org.gebish:geb-spock" : "1.1.1",
-	"org.powermock:powermock-core" : "1.6.2",
-	"org.powermock:powermock-api-support" : "1.6.2",
-	"org.powermock:powermock-module-junit4-common" : "1.6.2",
-	"org.powermock:powermock-module-junit4" : "1.6.2",
-	"org.powermock:powermock-api-mockito" : "1.6.2",
-	"org.powermock:powermock-reflect" : "1.6.2"
+	"org.gebish:geb-spock" : "1.1.1"
 ]
 
 configurations.all {
@@ -721,4 +715,4 @@ configurations.all {
 			details.useVersion deps[id]
 		}
 	}
-}
+}

+ 2 - 1
config/spring-security-config.gradle

@@ -52,7 +52,6 @@ dependencies {
 	testImplementation project(path: ':spring-security-saml2-service-provider', configuration: 'opensaml4MainCompile')
 	testImplementation project(path : ':spring-security-web', configuration : 'tests')
 	testImplementation apachedsDependencies
-	testImplementation powerMock2Dependencies
 	testImplementation 'com.squareup.okhttp3:mockwebserver'
 	testImplementation 'ch.qos.logback:logback-classic'
 	testImplementation 'io.projectreactor.netty:reactor-netty'
@@ -66,6 +65,8 @@ dependencies {
 	testImplementation 'org.eclipse.persistence:javax.persistence'
 	testImplementation 'org.hibernate:hibernate-entitymanager'
 	testImplementation 'org.hsqldb:hsqldb'
+	testImplementation 'org.mockito:mockito-core'
+	testImplementation "org.mockito:mockito-inline"
 	testImplementation ('org.openid4java:openid4java-nodeps') {
 		exclude group: 'com.google.code.guice', module: 'guice'
 	}

+ 24 - 28
config/src/test/java/org/springframework/security/config/SecurityNamespaceHandlerTests.java

@@ -19,13 +19,12 @@ package org.springframework.security.config;
 import org.apache.commons.logging.Log;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
-import org.springframework.messaging.Message;
 import org.springframework.security.config.util.InMemoryXmlApplicationContext;
 import org.springframework.test.util.ReflectionTestUtils;
 import org.springframework.util.ClassUtils;
@@ -41,9 +40,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
  * @author Rob Winch
  * @since 3.0
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ ClassUtils.class })
-@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*" })
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityNamespaceHandlerTests {
 
 	// @formatter:off
@@ -60,6 +57,9 @@ public class SecurityNamespaceHandlerTests {
 
 	private static final String FILTER_CHAIN_PROXY_CLASSNAME = "org.springframework.security.web.FilterChainProxy";
 
+	@Mock(answer = Answers.CALLS_REAL_METHODS)
+	private MockedStatic<ClassUtils> classUtils;
+
 	@Test
 	public void constructionSucceeds() {
 		new SecurityNamespaceHandler();
@@ -83,24 +83,18 @@ public class SecurityNamespaceHandlerTests {
 	@Test
 	public void initDoesNotLogErrorWhenFilterChainProxyFailsToLoad() throws Exception {
 		String className = "javax.servlet.Filter";
-		PowerMockito.spy(ClassUtils.class);
-		PowerMockito.doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName",
-				eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
 		Log logger = mock(Log.class);
 		SecurityNamespaceHandler handler = new SecurityNamespaceHandler();
 		ReflectionTestUtils.setField(handler, "logger", logger);
+		expectClassUtilsForNameThrowsNoClassDefFoundError(className);
 		handler.init();
-		PowerMockito.verifyStatic(ClassUtils.class);
-		ClassUtils.forName(eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
 		verifyZeroInteractions(logger);
 	}
 
 	@Test
 	public void filterNoClassDefFoundError() throws Exception {
 		String className = "javax.servlet.Filter";
-		PowerMockito.spy(ClassUtils.class);
-		PowerMockito.doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName",
-				eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
+		expectClassUtilsForNameThrowsNoClassDefFoundError(className);
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
 				.isThrownBy(() -> new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER + XML_HTTP_BLOCK))
 				.withMessageContaining("NoClassDefFoundError: " + className);
@@ -109,9 +103,7 @@ public class SecurityNamespaceHandlerTests {
 	@Test
 	public void filterNoClassDefFoundErrorNoHttpBlock() throws Exception {
 		String className = "javax.servlet.Filter";
-		PowerMockito.spy(ClassUtils.class);
-		PowerMockito.doThrow(new NoClassDefFoundError(className)).when(ClassUtils.class, "forName",
-				eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
+		expectClassUtilsForNameThrowsNoClassDefFoundError(className);
 		new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER);
 		// should load just fine since no http block
 	}
@@ -119,9 +111,7 @@ public class SecurityNamespaceHandlerTests {
 	@Test
 	public void filterChainProxyClassNotFoundException() throws Exception {
 		String className = FILTER_CHAIN_PROXY_CLASSNAME;
-		PowerMockito.spy(ClassUtils.class);
-		PowerMockito.doThrow(new ClassNotFoundException(className)).when(ClassUtils.class, "forName",
-				eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
+		expectClassUtilsForNameThrowsClassNotFoundException(className);
 		assertThatExceptionOfType(BeanDefinitionParsingException.class)
 				.isThrownBy(() -> new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER + XML_HTTP_BLOCK))
 				.withMessageContaining("ClassNotFoundException: " + className);
@@ -130,9 +120,7 @@ public class SecurityNamespaceHandlerTests {
 	@Test
 	public void filterChainProxyClassNotFoundExceptionNoHttpBlock() throws Exception {
 		String className = FILTER_CHAIN_PROXY_CLASSNAME;
-		PowerMockito.spy(ClassUtils.class);
-		PowerMockito.doThrow(new ClassNotFoundException(className)).when(ClassUtils.class, "forName",
-				eq(FILTER_CHAIN_PROXY_CLASSNAME), any(ClassLoader.class));
+		expectClassUtilsForNameThrowsClassNotFoundException(className);
 		new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER);
 		// should load just fine since no http block
 	}
@@ -140,11 +128,19 @@ public class SecurityNamespaceHandlerTests {
 	@Test
 	public void websocketNotFoundExceptionNoMessageBlock() throws Exception {
 		String className = FILTER_CHAIN_PROXY_CLASSNAME;
-		PowerMockito.spy(ClassUtils.class);
-		PowerMockito.doThrow(new ClassNotFoundException(className)).when(ClassUtils.class, "forName",
-				eq(Message.class.getName()), any(ClassLoader.class));
+		expectClassUtilsForNameThrowsClassNotFoundException(className);
 		new InMemoryXmlApplicationContext(XML_AUTHENTICATION_MANAGER);
 		// should load just fine since no websocket block
 	}
 
+	private void expectClassUtilsForNameThrowsNoClassDefFoundError(String className) {
+		this.classUtils.when(() -> ClassUtils.forName(eq(FILTER_CHAIN_PROXY_CLASSNAME), any()))
+				.thenThrow(new NoClassDefFoundError(className));
+	}
+
+	private void expectClassUtilsForNameThrowsClassNotFoundException(String className) {
+		this.classUtils.when(() -> ClassUtils.forName(eq(FILTER_CHAIN_PROXY_CLASSNAME), any()))
+				.thenThrow(new ClassNotFoundException(className));
+	}
+
 }

+ 11 - 13
config/src/test/java/org/springframework/security/config/annotation/web/WebSecurityConfigurerAdapterPowermockTests.java → config/src/test/java/org/springframework/security/config/annotation/web/WebSecurityConfigurerAdapterMockitoTests.java

@@ -23,10 +23,9 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.Mock;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.io.support.SpringFactoriesLoader;
@@ -56,11 +55,8 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
  * @author Rob Winch
  *
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ SpringFactoriesLoader.class, WebAsyncManager.class })
-@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*",
-		"javax.xml.transform.*" })
-public class WebSecurityConfigurerAdapterPowermockTests {
+@RunWith(MockitoJUnitRunner.class)
+public class WebSecurityConfigurerAdapterMockitoTests {
 
 	ConfigurableWebApplicationContext context;
 
@@ -70,6 +66,9 @@ public class WebSecurityConfigurerAdapterPowermockTests {
 	@Autowired
 	private MockMvc mockMvc;
 
+	@Mock
+	private MockedStatic<SpringFactoriesLoader> springFactoriesLoader;
+
 	@After
 	public void close() {
 		if (this.context != null) {
@@ -79,11 +78,10 @@ public class WebSecurityConfigurerAdapterPowermockTests {
 
 	@Test
 	public void loadConfigWhenDefaultConfigurerAsSpringFactoryhenDefaultConfigurerApplied() {
-		PowerMockito.spy(SpringFactoriesLoader.class);
 		DefaultConfigurer configurer = new DefaultConfigurer();
-		PowerMockito
-				.when(SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader()))
-				.thenReturn(Arrays.<AbstractHttpConfigurer>asList(configurer));
+		this.springFactoriesLoader.when(
+				() -> SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader()))
+				.thenReturn(Arrays.asList(configurer));
 		loadConfig(Config.class);
 		assertThat(configurer.init).isTrue();
 		assertThat(configurer.configure).isTrue();

+ 0 - 11
config/src/test/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurerServlet31Tests.java

@@ -16,17 +16,11 @@
 
 package org.springframework.security.config.annotation.web.configurers;
 
-import java.lang.reflect.Method;
-
 import javax.servlet.Filter;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@@ -50,13 +44,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 /**
  * @author Rob Winch
  */
-@RunWith(PowerMockRunner.class)
-@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*" })
 public class SessionManagementConfigurerServlet31Tests {
 
-	@Mock
-	Method method;
-
 	MockHttpServletRequest request;
 
 	MockHttpServletResponse response;

+ 0 - 14
config/src/test/java/org/springframework/security/config/http/SessionManagementConfigServlet31Tests.java

@@ -16,18 +16,11 @@
 
 package org.springframework.security.config.http;
 
-import java.lang.reflect.Method;
-
 import javax.servlet.Filter;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.mock.web.MockFilterChain;
@@ -38,7 +31,6 @@ import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextImpl;
 import org.springframework.security.web.context.HttpRequestResponseHolder;
 import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
-import org.springframework.util.ReflectionUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -46,9 +38,6 @@ import static org.assertj.core.api.Assertions.assertThat;
  * @author Rob Winch
  *
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ ReflectionUtils.class, Method.class })
-@PowerMockIgnore({ "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*", "javax.xml.parsers.*" })
 public class SessionManagementConfigServlet31Tests {
 
 	// @formatter:off
@@ -61,9 +50,6 @@ public class SessionManagementConfigServlet31Tests {
 			+ "</authentication-manager>";
 	// @formatter:on
 
-	@Mock
-	Method method;
-
 	MockHttpServletRequest request;
 
 	MockHttpServletResponse response;

+ 2 - 4
config/src/test/java/org/springframework/security/config/http/WebConfigUtilsTests.java

@@ -19,15 +19,13 @@ package org.springframework.security.config.http;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.beans.factory.xml.ParserContext;
 
 import static org.mockito.Mockito.verifyZeroInteractions;
 
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(ParserContext.class)
+@RunWith(MockitoJUnitRunner.class)
 public class WebConfigUtilsTests {
 
 	public static final String URL = "/url";

+ 2 - 1
core/spring-security-core.gradle

@@ -20,9 +20,10 @@ dependencies {
 	optional 'org.springframework:spring-tx'
 	optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
 
-	testImplementation powerMock2Dependencies
 	testImplementation 'commons-collections:commons-collections'
 	testImplementation 'io.projectreactor:reactor-test'
+	testImplementation 'org.mockito:mockito-core'
+	testImplementation 'org.mockito:mockito-inline'
 	testImplementation 'org.skyscreamer:jsonassert'
 	testImplementation 'org.slf4j:jcl-over-slf4j'
 	testImplementation 'org.springframework:spring-test'

+ 21 - 19
core/src/test/java/org/springframework/security/concurrent/AbstractDelegatingSecurityContextTestSupport.java

@@ -24,9 +24,8 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -41,8 +40,7 @@ import static org.mockito.ArgumentMatchers.eq;
  * @since 3.2
  *
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ DelegatingSecurityContextRunnable.class, DelegatingSecurityContextCallable.class })
+@RunWith(MockitoJUnitRunner.class)
 public abstract class AbstractDelegatingSecurityContextTestSupport {
 
 	@Mock
@@ -66,22 +64,26 @@ public abstract class AbstractDelegatingSecurityContextTestSupport {
 	@Mock
 	protected Runnable wrappedRunnable;
 
-	public final void explicitSecurityContextPowermockSetup() throws Exception {
-		PowerMockito.spy(DelegatingSecurityContextCallable.class);
-		PowerMockito.doReturn(this.wrappedCallable).when(DelegatingSecurityContextCallable.class, "create",
-				eq(this.callable), this.securityContextCaptor.capture());
-		PowerMockito.spy(DelegatingSecurityContextRunnable.class);
-		PowerMockito.doReturn(this.wrappedRunnable).when(DelegatingSecurityContextRunnable.class, "create",
-				eq(this.runnable), this.securityContextCaptor.capture());
+	@Mock
+	protected MockedStatic<DelegatingSecurityContextCallable> delegatingSecurityContextCallable;
+
+	@Mock
+	protected MockedStatic<DelegatingSecurityContextRunnable> delegatingSecurityContextRunnable;
+
+	public final void explicitSecurityContextSetup() throws Exception {
+		this.delegatingSecurityContextCallable.when(
+				() -> DelegatingSecurityContextCallable.create(eq(this.callable), this.securityContextCaptor.capture()))
+				.thenReturn(this.wrappedCallable);
+		this.delegatingSecurityContextRunnable.when(
+				() -> DelegatingSecurityContextRunnable.create(eq(this.runnable), this.securityContextCaptor.capture()))
+				.thenReturn(this.wrappedRunnable);
 	}
 
-	public final void currentSecurityContextPowermockSetup() throws Exception {
-		PowerMockito.spy(DelegatingSecurityContextCallable.class);
-		PowerMockito.doReturn(this.wrappedCallable).when(DelegatingSecurityContextCallable.class, "create",
-				this.callable, null);
-		PowerMockito.spy(DelegatingSecurityContextRunnable.class);
-		PowerMockito.doReturn(this.wrappedRunnable).when(DelegatingSecurityContextRunnable.class, "create",
-				this.runnable, null);
+	public final void currentSecurityContextSetup() throws Exception {
+		this.delegatingSecurityContextCallable.when(() -> DelegatingSecurityContextCallable.create(this.callable, null))
+				.thenReturn(this.wrappedCallable);
+		this.delegatingSecurityContextRunnable.when(() -> DelegatingSecurityContextRunnable.create(this.runnable, null))
+				.thenReturn(this.wrappedRunnable);
 	}
 
 	@Before

+ 1 - 1
core/src/test/java/org/springframework/security/concurrent/CurrentDelegatingSecurityContextExecutorServiceTests.java

@@ -33,7 +33,7 @@ public class CurrentDelegatingSecurityContextExecutorServiceTests
 
 	@Before
 	public void setUp() throws Exception {
-		super.currentSecurityContextPowermockSetup();
+		super.currentSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/concurrent/CurrentDelegatingSecurityContextExecutorTests.java

@@ -32,7 +32,7 @@ public class CurrentDelegatingSecurityContextExecutorTests extends AbstractDeleg
 
 	@Before
 	public void setUp() throws Exception {
-		super.currentSecurityContextPowermockSetup();
+		super.currentSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/concurrent/CurrentDelegatingSecurityContextScheduledExecutorServiceTests.java

@@ -33,7 +33,7 @@ public class CurrentDelegatingSecurityContextScheduledExecutorServiceTests
 
 	@Before
 	public void setUp() throws Exception {
-		this.currentSecurityContextPowermockSetup();
+		this.currentSecurityContextSetup();
 	}
 
 	@Override

+ 4 - 4
core/src/test/java/org/springframework/security/concurrent/DelegatingSecurityContextSupportTests.java

@@ -33,7 +33,7 @@ public class DelegatingSecurityContextSupportTests extends AbstractDelegatingSec
 
 	@Test
 	public void wrapCallable() throws Exception {
-		explicitSecurityContextPowermockSetup();
+		explicitSecurityContextSetup();
 		this.support = new ConcreteDelegatingSecurityContextSupport(this.securityContext);
 		assertThat(this.support.wrap(this.callable)).isSameAs(this.wrappedCallable);
 		assertThat(this.securityContextCaptor.getValue()).isSameAs(this.securityContext);
@@ -41,14 +41,14 @@ public class DelegatingSecurityContextSupportTests extends AbstractDelegatingSec
 
 	@Test
 	public void wrapCallableNullSecurityContext() throws Exception {
-		currentSecurityContextPowermockSetup();
+		currentSecurityContextSetup();
 		this.support = new ConcreteDelegatingSecurityContextSupport(null);
 		assertThat(this.support.wrap(this.callable)).isSameAs(this.wrappedCallable);
 	}
 
 	@Test
 	public void wrapRunnable() throws Exception {
-		explicitSecurityContextPowermockSetup();
+		explicitSecurityContextSetup();
 		this.support = new ConcreteDelegatingSecurityContextSupport(this.securityContext);
 		assertThat(this.support.wrap(this.runnable)).isSameAs(this.wrappedRunnable);
 		assertThat(this.securityContextCaptor.getValue()).isSameAs(this.securityContext);
@@ -56,7 +56,7 @@ public class DelegatingSecurityContextSupportTests extends AbstractDelegatingSec
 
 	@Test
 	public void wrapRunnableNullSecurityContext() throws Exception {
-		currentSecurityContextPowermockSetup();
+		currentSecurityContextSetup();
 		this.support = new ConcreteDelegatingSecurityContextSupport(null);
 		assertThat(this.support.wrap(this.runnable)).isSameAs(this.wrappedRunnable);
 	}

+ 1 - 1
core/src/test/java/org/springframework/security/concurrent/ExplicitDelegatingSecurityContextExecutorServiceTests.java

@@ -33,7 +33,7 @@ public class ExplicitDelegatingSecurityContextExecutorServiceTests
 
 	@Before
 	public void setUp() throws Exception {
-		super.explicitSecurityContextPowermockSetup();
+		super.explicitSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/concurrent/ExplicitDelegatingSecurityContextExecutorTests.java

@@ -32,7 +32,7 @@ public class ExplicitDelegatingSecurityContextExecutorTests extends AbstractDele
 
 	@Before
 	public void setUp() throws Exception {
-		super.explicitSecurityContextPowermockSetup();
+		super.explicitSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/concurrent/ExplicitDelegatingSecurityContextScheduledExecutorServiceTests.java

@@ -33,7 +33,7 @@ public class ExplicitDelegatingSecurityContextScheduledExecutorServiceTests
 
 	@Before
 	public void setUp() throws Exception {
-		this.explicitSecurityContextPowermockSetup();
+		this.explicitSecurityContextSetup();
 	}
 
 	@Override

+ 51 - 36
core/src/test/java/org/springframework/security/core/SpringSecurityCoreVersionTests.java

@@ -16,18 +16,22 @@
 
 package org.springframework.security.core;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
 import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Answers;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.powermock.reflect.Whitebox;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.core.SpringVersion;
+import org.springframework.util.ReflectionUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
@@ -42,21 +46,29 @@ import static org.mockito.Mockito.verifyZeroInteractions;
  * @author Luke Taylor
  * @author Rob Winch
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({ SpringSecurityCoreVersion.class, SpringVersion.class })
+@RunWith(MockitoJUnitRunner.class)
 public class SpringSecurityCoreVersionTests {
 
 	@Mock
 	private Log logger;
 
+	@Mock(answer = Answers.CALLS_REAL_METHODS)
+	private MockedStatic<SpringVersion> springVersion;
+
+	@Mock(answer = Answers.CALLS_REAL_METHODS)
+	private MockedStatic<SpringSecurityCoreVersion> springSecurityCoreVersion;
+
 	@Before
-	public void setup() {
-		Whitebox.setInternalState(SpringSecurityCoreVersion.class, this.logger);
+	public void setup() throws Exception {
+		Field logger = ReflectionUtils.findField(SpringSecurityCoreVersion.class, "logger");
+		StaticFinalReflectionUtils.setField(logger, this.logger);
 	}
 
 	@After
 	public void cleanup() throws Exception {
 		System.clearProperty(getDisableChecksProperty());
+		Field logger = ReflectionUtils.findField(SpringSecurityCoreVersion.class, "logger");
+		StaticFinalReflectionUtils.setField(logger, LogFactory.getLog(SpringSecurityCoreVersion.class));
 	}
 
 	@Test
@@ -79,40 +91,34 @@ public class SpringSecurityCoreVersionTests {
 	@Test
 	public void noLoggingIfVersionsAreEqual() throws Exception {
 		String version = "1";
-		PowerMockito.spy(SpringSecurityCoreVersion.class);
-		PowerMockito.spy(SpringVersion.class);
-		PowerMockito.doReturn(version).when(SpringSecurityCoreVersion.class, "getVersion");
-		PowerMockito.doReturn(version).when(SpringVersion.class, "getVersion");
+		expectSpringSecurityVersionThenReturn(version);
+		expectSpringVersionThenReturn(version);
 		performChecks();
 		verifyZeroInteractions(this.logger);
 	}
 
 	@Test
 	public void noLoggingIfSpringVersionNull() throws Exception {
-		PowerMockito.spy(SpringSecurityCoreVersion.class);
-		PowerMockito.spy(SpringVersion.class);
-		PowerMockito.doReturn("1").when(SpringSecurityCoreVersion.class, "getVersion");
-		PowerMockito.doReturn(null).when(SpringVersion.class, "getVersion");
+		String version = "1";
+		expectSpringSecurityVersionThenReturn(version);
+		expectSpringVersionThenReturn(null);
 		performChecks();
 		verifyZeroInteractions(this.logger);
 	}
 
 	@Test
 	public void warnIfSpringVersionTooSmall() throws Exception {
-		PowerMockito.spy(SpringSecurityCoreVersion.class);
-		PowerMockito.spy(SpringVersion.class);
-		PowerMockito.doReturn("3").when(SpringSecurityCoreVersion.class, "getVersion");
-		PowerMockito.doReturn("2").when(SpringVersion.class, "getVersion");
+		expectSpringSecurityVersionThenReturn("3");
+		expectSpringVersionThenReturn("2");
 		performChecks();
 		verify(this.logger, times(1)).warn(any());
 	}
 
 	@Test
 	public void noWarnIfSpringVersionLarger() throws Exception {
-		PowerMockito.spy(SpringSecurityCoreVersion.class);
-		PowerMockito.spy(SpringVersion.class);
-		PowerMockito.doReturn("4.0.0.RELEASE").when(SpringSecurityCoreVersion.class, "getVersion");
-		PowerMockito.doReturn("4.0.0.RELEASE").when(SpringVersion.class, "getVersion");
+		String version = "4.0.0.RELEASE";
+		expectSpringSecurityVersionThenReturn(version);
+		expectSpringVersionThenReturn(version);
 		performChecks();
 		verify(this.logger, never()).warn(any());
 	}
@@ -121,20 +127,16 @@ public class SpringSecurityCoreVersionTests {
 	@Test
 	public void noWarnIfSpringPatchVersionDoubleDigits() throws Exception {
 		String minSpringVersion = "3.2.8.RELEASE";
-		PowerMockito.spy(SpringSecurityCoreVersion.class);
-		PowerMockito.spy(SpringVersion.class);
-		PowerMockito.doReturn("3.2.0.RELEASE").when(SpringSecurityCoreVersion.class, "getVersion");
-		PowerMockito.doReturn("3.2.10.RELEASE").when(SpringVersion.class, "getVersion");
+		expectSpringSecurityVersionThenReturn("3.2.0.RELEASE");
+		expectSpringVersionThenReturn("3.2.10.RELEASE");
 		performChecks(minSpringVersion);
 		verify(this.logger, never()).warn(any());
 	}
 
 	@Test
 	public void noLoggingIfPropertySet() throws Exception {
-		PowerMockito.spy(SpringSecurityCoreVersion.class);
-		PowerMockito.spy(SpringVersion.class);
-		PowerMockito.doReturn("3").when(SpringSecurityCoreVersion.class, "getVersion");
-		PowerMockito.doReturn("2").when(SpringVersion.class, "getVersion");
+		expectSpringSecurityVersionThenReturn("3");
+		expectSpringVersionThenReturn("2");
 		System.setProperty(getDisableChecksProperty(), Boolean.TRUE.toString());
 		performChecks();
 		verifyZeroInteractions(this.logger);
@@ -144,12 +146,25 @@ public class SpringSecurityCoreVersionTests {
 		return SpringSecurityCoreVersion.class.getName().concat(".DISABLE_CHECKS");
 	}
 
-	private void performChecks() throws Exception {
-		Whitebox.invokeMethod(SpringSecurityCoreVersion.class, "performVersionChecks");
+	private void performChecks() {
+		Method method = ReflectionUtils.findMethod(SpringSecurityCoreVersion.class, "performVersionChecks");
+		ReflectionUtils.makeAccessible(method);
+		ReflectionUtils.invokeMethod(method, null);
+	}
+
+	private void performChecks(String minSpringVersion) {
+		Method method = ReflectionUtils.findMethod(SpringSecurityCoreVersion.class, "performVersionChecks",
+				String.class);
+		ReflectionUtils.makeAccessible(method);
+		ReflectionUtils.invokeMethod(method, null, minSpringVersion);
+	}
+
+	private void expectSpringSecurityVersionThenReturn(String version) {
+		this.springSecurityCoreVersion.when(SpringSecurityCoreVersion::getVersion).thenReturn(version);
 	}
 
-	private void performChecks(String minSpringVersion) throws Exception {
-		Whitebox.invokeMethod(SpringSecurityCoreVersion.class, "performVersionChecks", minSpringVersion);
+	private void expectSpringVersionThenReturn(String version) {
+		this.springVersion.when(SpringVersion::getVersion).thenReturn(version);
 	}
 
 }

+ 115 - 0
core/src/test/java/org/springframework/security/core/StaticFinalReflectionUtils.java

@@ -0,0 +1,115 @@
+/*
+ * Copyright 2008 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
+ *
+ *      https://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.security.core;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import sun.misc.Unsafe;
+
+import org.springframework.objenesis.instantiator.util.UnsafeUtils;
+
+/**
+ * Used for setting static variables even if they are private static final.
+ *
+ * The code in this class has been adopted from Powermock's <a href=
+ * "https://github.com/noushadali/powermock/blob/powermock-1.5.4/reflect/src/main/java/org/powermock/reflect/internal/WhiteboxImpl.java#L326">WhiteboxImpl</a>.
+ *
+ * @author Rob Winch
+ */
+final class StaticFinalReflectionUtils {
+
+	/**
+	 * Used to support setting static fields that are final using Java's Unsafe. If the
+	 * field is not static final, use
+	 * {@link org.springframework.test.util.ReflectionTestUtils}.
+	 * @param field the field to set
+	 * @param newValue the new value
+	 */
+	static void setField(final Field field, final Object newValue) {
+		try {
+			field.setAccessible(true);
+			int fieldModifiersMask = field.getModifiers();
+			boolean isFinalModifierPresent = (fieldModifiersMask & Modifier.FINAL) == Modifier.FINAL;
+			if (isFinalModifierPresent) {
+				AccessController.doPrivileged(new PrivilegedAction<Object>() {
+					@Override
+					public Object run() {
+						try {
+							Unsafe unsafe = UnsafeUtils.getUnsafe();
+							long offset = unsafe.staticFieldOffset(field);
+							Object base = unsafe.staticFieldBase(field);
+							setFieldUsingUnsafe(base, field.getType(), offset, newValue, unsafe);
+							return null;
+						}
+						catch (Throwable thrown) {
+							throw new RuntimeException(thrown);
+						}
+					}
+				});
+			}
+			else {
+				field.set(null, newValue);
+			}
+		}
+		catch (SecurityException ex) {
+			throw new RuntimeException(ex);
+		}
+		catch (IllegalAccessException ex) {
+			throw new RuntimeException(ex);
+		}
+		catch (IllegalArgumentException ex) {
+			throw new RuntimeException(ex);
+		}
+	}
+
+	private static void setFieldUsingUnsafe(Object base, Class type, long offset, Object newValue, Unsafe unsafe) {
+		if (type == Integer.TYPE) {
+			unsafe.putInt(base, offset, ((Integer) newValue));
+		}
+		else if (type == Short.TYPE) {
+			unsafe.putShort(base, offset, ((Short) newValue));
+		}
+		else if (type == Long.TYPE) {
+			unsafe.putLong(base, offset, ((Long) newValue));
+		}
+		else if (type == Byte.TYPE) {
+			unsafe.putByte(base, offset, ((Byte) newValue));
+		}
+		else if (type == Boolean.TYPE) {
+			unsafe.putBoolean(base, offset, ((Boolean) newValue));
+		}
+		else if (type == Float.TYPE) {
+			unsafe.putFloat(base, offset, ((Float) newValue));
+		}
+		else if (type == Double.TYPE) {
+			unsafe.putDouble(base, offset, ((Double) newValue));
+		}
+		else if (type == Character.TYPE) {
+			unsafe.putChar(base, offset, ((Character) newValue));
+		}
+		else {
+			unsafe.putObject(base, offset, newValue);
+		}
+	}
+
+	private StaticFinalReflectionUtils() {
+	}
+
+}

+ 1 - 1
core/src/test/java/org/springframework/security/scheduling/CurrentSecurityContextSchedulingTaskExecutorTests.java

@@ -33,7 +33,7 @@ public class CurrentSecurityContextSchedulingTaskExecutorTests
 
 	@Before
 	public void setUp() throws Exception {
-		currentSecurityContextPowermockSetup();
+		currentSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/scheduling/ExplicitSecurityContextSchedulingTaskExecutorTests.java

@@ -33,7 +33,7 @@ public class ExplicitSecurityContextSchedulingTaskExecutorTests
 
 	@Before
 	public void setUp() throws Exception {
-		explicitSecurityContextPowermockSetup();
+		explicitSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/task/CurrentDelegatingSecurityContextAsyncTaskExecutorTests.java

@@ -33,7 +33,7 @@ public class CurrentDelegatingSecurityContextAsyncTaskExecutorTests
 
 	@Before
 	public void setUp() throws Exception {
-		currentSecurityContextPowermockSetup();
+		currentSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/task/CurrentDelegatingSecurityContextTaskExecutorTests.java

@@ -41,7 +41,7 @@ public class CurrentDelegatingSecurityContextTaskExecutorTests extends AbstractD
 
 	@Before
 	public void setUp() throws Exception {
-		currentSecurityContextPowermockSetup();
+		currentSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/task/ExplicitDelegatingSecurityContextAsyncTaskExecutorTests.java

@@ -33,7 +33,7 @@ public class ExplicitDelegatingSecurityContextAsyncTaskExecutorTests
 
 	@Before
 	public void setUp() throws Exception {
-		explicitSecurityContextPowermockSetup();
+		explicitSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 1
core/src/test/java/org/springframework/security/task/ExplicitDelegatingSecurityContextTaskExecutorTests.java

@@ -41,7 +41,7 @@ public class ExplicitDelegatingSecurityContextTaskExecutorTests extends Abstract
 
 	@Before
 	public void setUp() throws Exception {
-		explicitSecurityContextPowermockSetup();
+		explicitSecurityContextSetup();
 	}
 
 	@Override

+ 1 - 6
dependencies/spring-security-dependencies.gradle

@@ -56,16 +56,11 @@ dependencies {
 		api "org.hsqldb:hsqldb:2.6.0"
 		api "org.jasig.cas.client:cas-client-core:3.6.2"
 		api "org.mockito:mockito-core:3.9.0"
+		api "org.mockito:mockito-inline:3.9.0"
 		api "org.openid4java:openid4java-nodeps:0.9.6"
 		api "org.opensaml:opensaml-core:$openSamlVersion"
 		api "org.opensaml:opensaml-saml-api:$openSamlVersion"
 		api "org.opensaml:opensaml-saml-impl:$openSamlVersion"
-		api "org.powermock:powermock-api-mockito2:2.0.9"
-		api "org.powermock:powermock-api-support:2.0.9"
-		api "org.powermock:powermock-core:2.0.9"
-		api "org.powermock:powermock-module-junit4-common:2.0.9"
-		api "org.powermock:powermock-module-junit4:2.0.9"
-		api "org.powermock:powermock-reflect:2.0.9"
 		api "org.python:jython:2.5.3"
 		api "org.seleniumhq.selenium:htmlunit-driver:2.49.1"
 		api "org.seleniumhq.selenium:selenium-java:3.141.59"

+ 1 - 1
messaging/spring-security-messaging.gradle

@@ -16,7 +16,7 @@ dependencies {
 
 	testImplementation project(path: ':spring-security-core', configuration: 'tests')
 	testImplementation 'commons-codec:commons-codec'
-	testImplementation powerMock2Dependencies
+	testImplementation 'org.mockito:mockito-core'
 	testImplementation slf4jDependencies
 
 	testRuntimeOnly 'org.hsqldb:hsqldb'

+ 1 - 1
oauth2/oauth2-client/spring-security-oauth2-client.gradle

@@ -18,7 +18,6 @@ dependencies {
 
 	testImplementation project(path: ':spring-security-oauth2-core', configuration: 'tests')
 	testImplementation project(path: ':spring-security-oauth2-jose', configuration: 'tests')
-	testImplementation powerMock2Dependencies
 	testImplementation 'com.squareup.okhttp3:mockwebserver'
 	testImplementation 'io.projectreactor.netty:reactor-netty'
 	testImplementation 'io.projectreactor:reactor-test'
@@ -26,6 +25,7 @@ dependencies {
 	testImplementation 'org.skyscreamer:jsonassert'
 	testImplementation 'io.r2dbc:r2dbc-h2:0.8.4.RELEASE'
 	testImplementation 'io.r2dbc:r2dbc-spi-test:0.8.5.RELEASE'
+	testImplementation 'org.mockito:mockito-core'
 
 	testRuntimeOnly 'org.hsqldb:hsqldb'
 

+ 1 - 1
oauth2/oauth2-core/spring-security-oauth2-core.gradle

@@ -10,5 +10,5 @@ dependencies {
 	optional 'com.nimbusds:oauth2-oidc-sdk'
 	optional 'org.springframework:spring-webflux'
 
-	testImplementation powerMock2Dependencies
+	testImplementation 'org.mockito:mockito-core'
 }

+ 1 - 1
oauth2/oauth2-jose/spring-security-oauth2-jose.gradle

@@ -10,8 +10,8 @@ dependencies {
 	optional 'io.projectreactor:reactor-core'
 	optional 'org.springframework:spring-webflux'
 
-	testImplementation powerMock2Dependencies
 	testImplementation 'com.squareup.okhttp3:mockwebserver'
 	testImplementation 'io.projectreactor.netty:reactor-netty'
 	testImplementation 'com.fasterxml.jackson.core:jackson-databind'
+	testImplementation 'org.mockito:mockito-core'
 }

+ 2 - 1
test/spring-security-test.gradle

@@ -22,8 +22,9 @@ dependencies {
 	testImplementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
 	testImplementation 'io.projectreactor:reactor-test'
 	testImplementation 'javax.xml.bind:jaxb-api'
+	testImplementation 'org.mockito:mockito-core'
+	testImplementation 'org.mockito:mockito-inline'
 	testImplementation 'org.skyscreamer:jsonassert'
 	testImplementation 'org.springframework:spring-webmvc'
 	testImplementation 'org.springframework:spring-tx'
-	testImplementation powerMock2Dependencies
 }

+ 8 - 14
test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsAuthenticationTests.java

@@ -25,10 +25,8 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.core.Authentication;
@@ -43,10 +41,7 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
 
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(WebTestUtils.class)
-@PowerMockIgnore({ "javax.security.auth.*", "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*",
-		"javax.xml.parsers.*" })
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityMockMvcRequestPostProcessorsAuthenticationTests {
 
 	@Captor
@@ -60,10 +55,14 @@ public class SecurityMockMvcRequestPostProcessorsAuthenticationTests {
 	@Mock
 	private Authentication authentication;
 
+	@Mock
+	private MockedStatic<WebTestUtils> webTestUtils;
+
 	@Before
 	public void setup() {
 		this.request = new MockHttpServletRequest();
-		mockWebTestUtils();
+		this.webTestUtils.when(() -> WebTestUtils.getSecurityContextRepository(this.request))
+				.thenReturn(this.repository);
 	}
 
 	@After
@@ -80,9 +79,4 @@ public class SecurityMockMvcRequestPostProcessorsAuthenticationTests {
 		assertThat(context.getAuthentication()).isSameAs(this.authentication);
 	}
 
-	private void mockWebTestUtils() {
-		PowerMockito.spy(WebTestUtils.class);
-		PowerMockito.when(WebTestUtils.getSecurityContextRepository(this.request)).thenReturn(this.repository);
-	}
-
 }

+ 8 - 14
test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsSecurityContextTests.java

@@ -25,10 +25,8 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.core.context.SecurityContext;
@@ -42,10 +40,7 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.securityContext;
 
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(WebTestUtils.class)
-@PowerMockIgnore({ "javax.security.auth.*", "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*",
-		"javax.xml.parsers.*" })
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityMockMvcRequestPostProcessorsSecurityContextTests {
 
 	@Captor
@@ -59,10 +54,14 @@ public class SecurityMockMvcRequestPostProcessorsSecurityContextTests {
 	@Mock
 	private SecurityContext expectedContext;
 
+	@Mock
+	private MockedStatic<WebTestUtils> webTestUtils;
+
 	@Before
 	public void setup() {
 		this.request = new MockHttpServletRequest();
-		mockWebTestUtils();
+		this.webTestUtils.when(() -> WebTestUtils.getSecurityContextRepository(this.request))
+				.thenReturn(this.repository);
 	}
 
 	@After
@@ -79,9 +78,4 @@ public class SecurityMockMvcRequestPostProcessorsSecurityContextTests {
 		assertThat(context).isSameAs(this.expectedContext);
 	}
 
-	private void mockWebTestUtils() {
-		PowerMockito.spy(WebTestUtils.class);
-		PowerMockito.when(WebTestUtils.getSecurityContextRepository(this.request)).thenReturn(this.repository);
-	}
-
 }

+ 8 - 14
test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsTestSecurityContextTests.java

@@ -23,10 +23,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.core.context.SecurityContext;
@@ -40,10 +38,7 @@ import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.testSecurityContext;
 
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(WebTestUtils.class)
-@PowerMockIgnore({ "javax.security.auth.*", "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*",
-		"javax.xml.parsers.*" })
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityMockMvcRequestPostProcessorsTestSecurityContextTests {
 
 	@Mock
@@ -52,12 +47,16 @@ public class SecurityMockMvcRequestPostProcessorsTestSecurityContextTests {
 	@Mock
 	private SecurityContextRepository repository;
 
+	@Mock
+	private MockedStatic<WebTestUtils> webTestUtils;
+
 	private MockHttpServletRequest request;
 
 	@Before
 	public void setup() {
 		this.request = new MockHttpServletRequest();
-		mockWebTestUtils();
+		this.webTestUtils.when(() -> WebTestUtils.getSecurityContextRepository(this.request))
+				.thenReturn(this.repository);
 	}
 
 	@After
@@ -80,9 +79,4 @@ public class SecurityMockMvcRequestPostProcessorsTestSecurityContextTests {
 				any(HttpServletResponse.class));
 	}
 
-	private void mockWebTestUtils() {
-		PowerMockito.spy(WebTestUtils.class);
-		PowerMockito.when(WebTestUtils.getSecurityContextRepository(this.request)).thenReturn(this.repository);
-	}
-
 }

+ 8 - 14
test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsUserDetailsTests.java

@@ -25,10 +25,8 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -44,10 +42,7 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
 
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(WebTestUtils.class)
-@PowerMockIgnore({ "javax.security.auth.*", "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*",
-		"javax.xml.parsers.*" })
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityMockMvcRequestPostProcessorsUserDetailsTests {
 
 	@Captor
@@ -61,10 +56,14 @@ public class SecurityMockMvcRequestPostProcessorsUserDetailsTests {
 	@Mock
 	private UserDetails userDetails;
 
+	@Mock
+	private MockedStatic<WebTestUtils> webTestUtils;
+
 	@Before
 	public void setup() {
 		this.request = new MockHttpServletRequest();
-		mockWebTestUtils();
+		this.webTestUtils.when(() -> WebTestUtils.getSecurityContextRepository(this.request))
+				.thenReturn(this.repository);
 	}
 
 	@After
@@ -82,9 +81,4 @@ public class SecurityMockMvcRequestPostProcessorsUserDetailsTests {
 		assertThat(context.getAuthentication().getPrincipal()).isSameAs(this.userDetails);
 	}
 
-	private void mockWebTestUtils() {
-		PowerMockito.spy(WebTestUtils.class);
-		PowerMockito.when(WebTestUtils.getSecurityContextRepository(this.request)).thenReturn(this.repository);
-	}
-
 }

+ 8 - 14
test/src/test/java/org/springframework/security/test/web/servlet/request/SecurityMockMvcRequestPostProcessorsUserTests.java

@@ -28,10 +28,8 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.MockedStatic;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -48,10 +46,7 @@ import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
 
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(WebTestUtils.class)
-@PowerMockIgnore({ "javax.security.auth.*", "org.w3c.dom.*", "org.xml.sax.*", "org.apache.xerces.*",
-		"javax.xml.parsers.*" })
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityMockMvcRequestPostProcessorsUserTests {
 
 	@Captor
@@ -68,10 +63,14 @@ public class SecurityMockMvcRequestPostProcessorsUserTests {
 	@Mock
 	private GrantedAuthority authority2;
 
+	@Mock
+	private MockedStatic<WebTestUtils> webTestUtils;
+
 	@Before
 	public void setup() {
 		this.request = new MockHttpServletRequest();
-		mockWebTestUtils();
+		this.webTestUtils.when(() -> WebTestUtils.getSecurityContextRepository(this.request))
+				.thenReturn(this.repository);
 	}
 
 	@After
@@ -134,9 +133,4 @@ public class SecurityMockMvcRequestPostProcessorsUserTests {
 				this.authority2);
 	}
 
-	private void mockWebTestUtils() {
-		PowerMockito.spy(WebTestUtils.class);
-		PowerMockito.when(WebTestUtils.getSecurityContextRepository(this.request)).thenReturn(this.repository);
-	}
-
 }

+ 2 - 1
web/spring-security-web.gradle

@@ -23,10 +23,11 @@ dependencies {
 	testImplementation 'commons-codec:commons-codec'
 	testImplementation 'io.projectreactor:reactor-test'
 	testImplementation 'javax.xml.bind:jaxb-api'
+	testImplementation 'org.mockito:mockito-core'
+	testImplementation 'org.mockito:mockito-inline'
 	testImplementation 'org.skyscreamer:jsonassert'
 	testImplementation 'org.springframework:spring-webflux'
 	testImplementation 'org.synchronoss.cloud:nio-multipart-parser'
-	testImplementation powerMock2Dependencies
 
 	testRuntimeOnly 'org.hsqldb:hsqldb'
 }

+ 0 - 8
web/src/test/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServicesTests.java

@@ -22,11 +22,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 import org.mockito.Mockito;
-import org.powermock.core.classloader.annotations.PowerMockIgnore;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.springframework.context.MessageSource;
 import org.springframework.mock.web.MockHttpServletRequest;
@@ -40,7 +36,6 @@ import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.util.ReflectionUtils;
 import org.springframework.util.StringUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -55,9 +50,6 @@ import static org.mockito.Mockito.verify;
  * @author Luke Taylor
  */
 @SuppressWarnings("unchecked")
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(ReflectionUtils.class)
-@PowerMockIgnore("javax.security.auth.*")
 public class AbstractRememberMeServicesTests {
 
 	static User joe = new User("joe", "password", true, true, true, true, AuthorityUtils.createAuthorityList("ROLE_A"));

+ 0 - 3
web/src/test/java/org/springframework/security/web/authentication/session/ChangeSessionIdAuthenticationStrategyTests.java

@@ -17,8 +17,6 @@
 package org.springframework.security.web.authentication.session;
 
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 
@@ -28,7 +26,6 @@ import static org.assertj.core.api.Assertions.assertThat;
  * @author Rob Winch
  *
  */
-@RunWith(PowerMockRunner.class)
 public class ChangeSessionIdAuthenticationStrategyTests {
 
 	@Test

+ 2 - 4
web/src/test/java/org/springframework/security/web/debug/DebugFilterTests.java

@@ -29,8 +29,7 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.security.web.FilterChainProxy;
@@ -48,8 +47,7 @@ import static org.mockito.Mockito.verify;
  * @author Rob Winch
  *
  */
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(Logger.class)
+@RunWith(MockitoJUnitRunner.class)
 public class DebugFilterTests {
 
 	@Captor

+ 0 - 6
web/src/test/java/org/springframework/security/web/header/writers/CacheControlHeadersWriterTests.java

@@ -18,14 +18,10 @@ package org.springframework.security.web.header.writers;
 
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.core.classloader.annotations.PrepareOnlyThisForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 
 import org.springframework.http.HttpStatus;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
-import org.springframework.util.ReflectionUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -33,8 +29,6 @@ import static org.assertj.core.api.Assertions.assertThat;
  * @author Rob Winch
  *
  */
-@RunWith(PowerMockRunner.class)
-@PrepareOnlyThisForTest(ReflectionUtils.class)
 public class CacheControlHeadersWriterTests {
 
 	private MockHttpServletRequest request;

+ 2 - 7
web/src/test/java/org/springframework/security/web/servletapi/SecurityContextHolderAwareRequestFilterTests.java

@@ -32,8 +32,7 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Captor;
 import org.mockito.Mock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
@@ -48,7 +47,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.web.AuthenticationEntryPoint;
 import org.springframework.security.web.authentication.logout.LogoutHandler;
 import org.springframework.test.util.ReflectionTestUtils;
-import org.springframework.util.ClassUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -69,8 +67,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
  * @author Rob Winch
  * @author Eddú Meléndez
  */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(ClassUtils.class)
+@RunWith(MockitoJUnitRunner.class)
 public class SecurityContextHolderAwareRequestFilterTests {
 
 	@Captor
@@ -176,8 +173,6 @@ public class SecurityContextHolderAwareRequestFilterTests {
 	@Test
 	public void loginWithExistingUser() throws Exception {
 		TestingAuthenticationToken expectedAuth = new TestingAuthenticationToken("user", "password", "ROLE_USER");
-		given(this.authenticationManager.authenticate(any(UsernamePasswordAuthenticationToken.class)))
-				.willReturn(new TestingAuthenticationToken("newuser", "not be found", "ROLE_USER"));
 		SecurityContextHolder.getContext().setAuthentication(expectedAuth);
 		assertThatExceptionOfType(ServletException.class).isThrownBy(
 				() -> wrappedRequest().login(expectedAuth.getName(), String.valueOf(expectedAuth.getCredentials())));