Skip to content

Commit

Permalink
Remove Powermock
Browse files Browse the repository at this point in the history
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 spring-projectsgh-6025
  • Loading branch information
rwinch authored and Ayush Kohli committed Aug 25, 2021
1 parent 2ed5836 commit d132935
Show file tree
Hide file tree
Showing 43 changed files with 300 additions and 286 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ repositories {
dependencies {
testCompile spockDependencies
testCompile gebDependencies
testCompile powerMockDependencies
testCompile seleniumDependencies
testCompile slf4jDependencies
testCompile springCoreDependency
testCompile jstlDependencies
testCompile apachedsDependencies
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -721,4 +715,4 @@ configurations.all {
details.useVersion deps[id]
}
}
}
}
3 changes: 2 additions & 1 deletion config/spring-security-config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@
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;
Expand All @@ -41,9 +40,7 @@
* @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
Expand All @@ -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();
Expand All @@ -83,24 +83,18 @@ public void pre32SchemaAreNotSupported() {
@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);
Expand All @@ -109,19 +103,15 @@ public void filterNoClassDefFoundError() throws Exception {
@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
}

@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);
Expand All @@ -130,21 +120,27 @@ public void filterChainProxyClassNotFoundException() throws Exception {
@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
}

@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));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@
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;
Expand Down Expand Up @@ -56,11 +55,8 @@
* @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;

Expand All @@ -70,6 +66,9 @@ public class WebSecurityConfigurerAdapterPowermockTests {
@Autowired
private MockMvc mockMvc;

@Mock
private MockedStatic<SpringFactoriesLoader> springFactoriesLoader;

@After
public void close() {
if (this.context != null) {
Expand All @@ -79,11 +78,10 @@ public void close() {

@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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -50,13 +44,8 @@
/**
* @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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -38,17 +31,13 @@
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;

/**
* @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
Expand All @@ -61,9 +50,6 @@ public class SessionManagementConfigServlet31Tests {
+ "</authentication-manager>";
// @formatter:on

@Mock
Method method;

MockHttpServletRequest request;

MockHttpServletResponse response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@
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";
Expand Down
3 changes: 2 additions & 1 deletion core/spring-security-core.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Loading

0 comments on commit d132935

Please sign in to comment.