You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bm...@apache.org on 2021/01/13 15:06:23 UTC

[shiro] 03/05: (build) fix JDK 16/17 by replacing some EasyMock tests with Mockito, illegal-access=permit for guice tests. Remove JDK17 for now.

This is an automated email from the ASF dual-hosted git repository.

bmarwell pushed a commit to branch SHIRO-290
in repository https://gitbox.apache.org/repos/asf/shiro.git

commit 5cb30ea34930e25f2a8a40f6c834dff9edaa1745
Author: Benjamin Marwell <bm...@apache.org>
AuthorDate: Fri Jan 10 22:01:10 2020 +0100

    (build) fix JDK 16/17 by replacing some EasyMock tests with Mockito, illegal-access=permit for guice tests. Remove JDK17 for now.
---
 .github/workflows/maven.yml                        |   2 +-
 integration-tests/guice3/pom.xml                   |  12 +++
 integration-tests/guice4/pom.xml                   |  12 +++
 pom.xml                                            |  20 ++++
 samples/guice/pom.xml                              |  12 +++
 support/guice/pom.xml                              |  12 +++
 .../apache/shiro/guice/BeanTypeListenerTest.java   |  56 +++++-----
 .../cache/HazelcastCacheManagerTest.groovy         |  54 ++++------
 support/jaxrs/pom.xml                              |   6 ++
 .../shiro/web/jaxrs/ExceptionMapperTest.groovy     |  22 ++--
 .../ShiroEventBusAwareBeanPostProcessorTest.groovy |  16 +--
 .../servlet/ShiroHttpServletResponseTest.groovy    | 118 +++++++++++----------
 .../web/env/EnvironmentLoaderServiceTest.java      |  30 +++---
 13 files changed, 218 insertions(+), 154 deletions(-)

diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index cf0c5dd..a5be92a 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -25,7 +25,7 @@ jobs:
     strategy:
       matrix:
         os: [ ubuntu-latest, windows-latest, macOS-latest ]
-        java: [ 8, 11, 15, 16-ea, 17-ea ]
+        java: [ 8, 11, 15, 16-ea ]
       fail-fast: false
 
     runs-on: ${{ matrix.os }}
diff --git a/integration-tests/guice3/pom.xml b/integration-tests/guice3/pom.xml
index 37326b4..9b8b3ec 100644
--- a/integration-tests/guice3/pom.xml
+++ b/integration-tests/guice3/pom.xml
@@ -123,4 +123,16 @@
         </dependency>
 	</dependencies>
 
+	<profiles>
+		<profile>
+			<id>jdk16</id>
+			<activation>
+				<jdk>[16,)</jdk>
+			</activation>
+			<properties>
+				<surefire.argLine>--illegal-access=permit</surefire.argLine>
+				<failsafe.argLine>--illegal-access=permit</failsafe.argLine>
+			</properties>
+		</profile>
+	</profiles>
 </project>
diff --git a/integration-tests/guice4/pom.xml b/integration-tests/guice4/pom.xml
index 37f45ca..8f76d1e 100644
--- a/integration-tests/guice4/pom.xml
+++ b/integration-tests/guice4/pom.xml
@@ -128,4 +128,16 @@
         </dependency>
 	</dependencies>
 
+	<profiles>
+		<profile>
+			<id>jdk16</id>
+			<activation>
+				<jdk>[16,)</jdk>
+			</activation>
+			<properties>
+				<surefire.argLine>--illegal-access=permit</surefire.argLine>
+				<failsafe.argLine>--illegal-access=permit</failsafe.argLine>
+			</properties>
+		</profile>
+	</profiles>
 </project>
diff --git a/pom.xml b/pom.xml
index 4228c1f..5b3a682 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,6 +70,10 @@
         <!-- Replaced by the build number plugin at build time: -->
         <buildNumber>${user.name}-${maven.build.timestamp}</buildNumber>
         <jacoco.skip>true</jacoco.skip>
+        <!--suppress CheckTagEmptyBody -->
+        <surefire.argLine></surefire.argLine>
+        <!--suppress CheckTagEmptyBody -->
+        <failsafe.argLine></failsafe.argLine>
 
         <!-- non-dependency-based properties: -->
         <shiro.osgi.importRange>[2, 3)</shiro.osgi.importRange>
@@ -110,6 +114,7 @@
 
         <!-- Test 3rd-party dependencies: -->
         <easymock.version>4.0.2</easymock.version>
+        <mockito.version>3.7.0</mockito.version>
         <gmaven.version>1.12.0</gmaven.version>
         <groovy.version>3.0.7</groovy.version>
         <junit.version>5.6.2</junit.version>
@@ -433,6 +438,7 @@
                 <configuration>
                     <printSummary>true</printSummary>
                     <useSystemClassLoader>false</useSystemClassLoader>
+                    <argLine>${surefire.argLine}</argLine>
                 </configuration>
             </plugin>
             <plugin>
@@ -450,6 +456,7 @@
                         <exclude>**/*ManualIT.java</exclude>
                         <exclude>**/*ManualIT.groovy</exclude>
                     </excludes>
+                    <argLine>${failsafe.argLine}</argLine>
                 </configuration>
                 <executions>
                     <execution>
@@ -690,6 +697,12 @@
             <version>${easymock.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>${mockito.version}</version>
+            <scope>test</scope>
+        </dependency>
         <!-- Writing tests in groovy is fast!: -->
         <dependency>
             <groupId>org.codehaus.groovy</groupId>
@@ -1230,6 +1243,7 @@
                         <link>https://docs.spring.io/spring/docs/2.5.x/javadoc-api/</link>
                         <link>https://junit.org/junit4/javadoc/4.12/</link>
                         <link>http://easymock.org/api/easymock/2.4</link>
+                        <link>https://javadoc.io/doc/org.mockito/mockito-core/${mockito.version}/org/mockito/Mockito.html</link>
                         <link>https://www.quartz-scheduler.org/api/1.8.6/</link>
                     </links>
                     <!-- Don't include the sample apps - they're not part of Shiro's API: -->
@@ -1401,6 +1415,12 @@
             </build>
         </profile>
         <profile>
+            <id>jdk16</id>
+            <activation>
+                <jdk>[16,)</jdk>
+            </activation>
+        </profile>
+        <profile>
             <id>docs</id>
             <build>
                 <plugins>
diff --git a/samples/guice/pom.xml b/samples/guice/pom.xml
index d1ee44d..673e6e6 100644
--- a/samples/guice/pom.xml
+++ b/samples/guice/pom.xml
@@ -113,4 +113,16 @@
 		</dependency>
 	</dependencies>
 
+	<profiles>
+		<profile>
+			<id>jdk16</id>
+			<activation>
+				<jdk>[16,)</jdk>
+			</activation>
+			<properties>
+				<surefire.argLine>--illegal-access=permit</surefire.argLine>
+				<failsafe.argLine>--illegal-access=permit</failsafe.argLine>
+			</properties>
+		</profile>
+	</profiles>
 </project>
diff --git a/support/guice/pom.xml b/support/guice/pom.xml
index 7b2c50e..a656c40 100644
--- a/support/guice/pom.xml
+++ b/support/guice/pom.xml
@@ -121,4 +121,16 @@
             </plugin>
         </plugins>
     </build>
+
+    <profiles>
+        <profile>
+            <id>jdk16</id>
+            <activation>
+                <jdk>[16,)</jdk>
+            </activation>
+            <properties>
+                <surefire.argLine>--illegal-access=permit</surefire.argLine>
+            </properties>
+        </profile>
+    </profiles>
 </project>
diff --git a/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java b/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
index 68e178d..421ae32 100644
--- a/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
+++ b/support/guice/src/test/java/org/apache/shiro/guice/BeanTypeListenerTest.java
@@ -18,24 +18,33 @@
  */
 package org.apache.shiro.guice;
 
-import com.google.inject.*;
+import com.google.inject.ConfigurationException;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.MembersInjector;
+import com.google.inject.Provider;
+import com.google.inject.TypeLiteral;
 import com.google.inject.name.Names;
 import com.google.inject.spi.Message;
 import com.google.inject.spi.TypeEncounter;
-import org.apache.shiro.guice.aop.ShiroAopModule;
-import org.apache.shiro.guice.web.ShiroWebModule;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.aop.DefaultAnnotationResolver;
 import org.apache.shiro.crypto.cipher.BlowfishCipherService;
-import org.easymock.Capture;
-import org.easymock.IMocksControl;
+import org.apache.shiro.guice.aop.ShiroAopModule;
+import org.apache.shiro.guice.web.ShiroWebModule;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 
 import java.util.Collections;
 import java.util.Map;
 
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 /**
  * Test Cases::
@@ -64,29 +73,25 @@ public class BeanTypeListenerTest {
 
     @Test
     public void testPropertySetting() throws Exception {
-        IMocksControl control = createControl();
-        TypeEncounter<SomeInjectableBean> encounter = control.createMock(TypeEncounter.class);
+        TypeEncounter<SomeInjectableBean> encounter = mock(TypeEncounter.class);
 
-        Provider<Injector> injectorProvider = control.createMock(Provider.class);
-        Injector injector = control.createMock(Injector.class);
+        Provider<Injector> injectorProvider = mock(Provider.class);
+        Injector injector = mock(Injector.class);
 
-        expect(encounter.getProvider(Injector.class)).andReturn(injectorProvider);
+        when(encounter.getProvider(Injector.class)).then(args -> injectorProvider);
 
-        expect(injectorProvider.get()).andReturn(injector).anyTimes();
+        when(injectorProvider.get()).then(args -> injector);
 
-        Capture<MembersInjector<SomeInjectableBean>> capture = Capture.newInstance();
-        encounter.register(and(anyObject(MembersInjector.class), capture(capture)));
+        ArgumentCaptor<MembersInjector<SomeInjectableBean>> captor = ArgumentCaptor.forClass(MembersInjector.class);
 
-        SecurityManager securityManager = control.createMock(SecurityManager.class);
+        SecurityManager securityManager = mock(SecurityManager.class);
         String property = "myPropertyValue";
 
-        expect(injector.getInstance(Key.get(SecurityManager.class))).andReturn(securityManager);
-        expect(injector.getInstance(Key.get(String.class, Names.named("shiro.myProperty")))).andReturn(property);
-        expect(injector.getInstance(Key.get(String.class, Names.named("shiro.unavailableProperty"))))
-                .andThrow(new ConfigurationException(Collections.singleton(new Message("Not Available!"))));
-        expect((Map)injector.getInstance(BeanTypeListener.MAP_KEY)).andReturn(Collections.EMPTY_MAP).anyTimes();
-
-        control.replay();
+        when(injector.getInstance(Key.get(SecurityManager.class))).then(args -> securityManager);
+        when(injector.getInstance(Key.get(String.class, Names.named("shiro.myProperty")))).then(args -> property);
+        when(injector.getInstance(Key.get(String.class, Names.named("shiro.unavailableProperty"))))
+                .thenThrow(new ConfigurationException(Collections.singleton(new Message("Not Available!"))));
+        when((Map) injector.getInstance(BeanTypeListener.MAP_KEY)).then(args -> Collections.EMPTY_MAP);
 
         BeanTypeListener underTest = new BeanTypeListener();
 
@@ -94,13 +99,12 @@ public class BeanTypeListenerTest {
 
         SomeInjectableBean bean = new SomeInjectableBean();
 
-        capture.getValue().injectMembers(bean);
+        verify(encounter).register(captor.capture());
+        captor.getValue().injectMembers(bean);
 
         assertSame(securityManager, bean.securityManager);
         assertSame(property, bean.myProperty);
         assertNull(bean.unavailableProperty);
-
-        control.verify();
     }
 
     public static class SomeInjectableBean {
diff --git a/support/hazelcast/src/test/groovy/org/apache/shiro/hazelcast/cache/HazelcastCacheManagerTest.groovy b/support/hazelcast/src/test/groovy/org/apache/shiro/hazelcast/cache/HazelcastCacheManagerTest.groovy
index e8901a2..937f405 100644
--- a/support/hazelcast/src/test/groovy/org/apache/shiro/hazelcast/cache/HazelcastCacheManagerTest.groovy
+++ b/support/hazelcast/src/test/groovy/org/apache/shiro/hazelcast/cache/HazelcastCacheManagerTest.groovy
@@ -23,8 +23,8 @@ import com.hazelcast.core.HazelcastInstance
 import com.hazelcast.core.LifecycleService
 import org.junit.Test
 
-import static org.easymock.EasyMock.*
 import static org.junit.Assert.*
+import static org.mockito.Mockito.*
 
 /**
  * Unit tests for {@link HazelcastCacheManager}.
@@ -40,15 +40,11 @@ class HazelcastCacheManagerTest {
         HazelcastInstance hc = mock(HazelcastInstance)
         def manager = new HazelcastCacheManager();
 
-        replay hc
-
         // when
         manager.hazelcastInstance = hc
 
         // then
         assertSame hc, manager.hazelcastInstance
-
-        verify hc
     }
 
     @Test
@@ -69,35 +65,31 @@ class HazelcastCacheManagerTest {
     void testImplicitlyCreated() {
 
         // given
-        HazelcastInstance hazelcastInstance = niceMock(HazelcastInstance)
+        HazelcastInstance hazelcastInstance = mock(HazelcastInstance)
 
-        HazelcastCacheManager manager = createMockBuilder(HazelcastCacheManager)
-                .addMockedMethod("createHazelcastInstance")
-                .niceMock();
-        expect(manager.createHazelcastInstance()).andReturn(hazelcastInstance)
+        HazelcastCacheManager manager = spy(HazelcastCacheManager);
+        when(manager.createHazelcastInstance()).then(args -> hazelcastInstance)
 
         // when
         manager.init()
 
         // then
         assertTrue manager.implicitlyCreated
+        manager.destroy()
     }
 
     @Test
     void testDestroy() {
 
         // given
-        LifecycleService lifecycleService = niceMock(LifecycleService)
+        LifecycleService lifecycleService = mock(LifecycleService)
 
-        HazelcastInstance hazelcastInstance = niceMock(HazelcastInstance)
-        expect(hazelcastInstance.getLifecycleService()).andReturn(lifecycleService)
+        HazelcastInstance hazelcastInstance = spy(HazelcastInstance)
+        when(hazelcastInstance.getLifecycleService()).then(args -> lifecycleService)
 
-        HazelcastCacheManager manager = createMockBuilder(HazelcastCacheManager)
-                .addMockedMethod("createHazelcastInstance")
-                .niceMock();
-        expect(manager.createHazelcastInstance()).andReturn(hazelcastInstance)
+        HazelcastCacheManager manager = spy(HazelcastCacheManager);
+        when(manager.createHazelcastInstance()).then(args -> hazelcastInstance)
 
-        replay lifecycleService, hazelcastInstance, manager
 
         // when
         manager.init()
@@ -106,20 +98,18 @@ class HazelcastCacheManagerTest {
         // then
         assertFalse manager.implicitlyCreated
         assertNull manager.hazelcastInstance
-        verify hazelcastInstance
-        verify manager
+        verify(hazelcastInstance).getLifecycleService()
+        verify(manager).createHazelcastInstance()
     }
 
     @Test
     void testDestroyExplicit() {
 
         // given
-        HazelcastInstance hazelcastInstance = niceMock(HazelcastInstance)
+        HazelcastInstance hazelcastInstance = mock(HazelcastInstance)
         HazelcastCacheManager manager = new HazelcastCacheManager()
         manager.hazelcastInstance = hazelcastInstance
 
-        replay hazelcastInstance
-
         // when
         manager.init()
         manager.destroy()
@@ -134,17 +124,13 @@ class HazelcastCacheManagerTest {
 
         // given
         LifecycleService lifecycleService = mock(LifecycleService)
-        expect(lifecycleService.shutdown()).andThrow(new IllegalStateException())
+        when(lifecycleService.shutdown()).thenThrow(new IllegalStateException())
 
         HazelcastInstance hazelcastInstance = mock(HazelcastInstance)
-        expect(hazelcastInstance.getLifecycleService()).andReturn(lifecycleService)
-
-        HazelcastCacheManager manager = createMockBuilder(HazelcastCacheManager)
-                .addMockedMethod("createHazelcastInstance")
-                .niceMock();
-        expect(manager.createHazelcastInstance()).andReturn(hazelcastInstance)
+        when(hazelcastInstance.getLifecycleService()).then(args -> lifecycleService)
 
-        replay lifecycleService, hazelcastInstance, manager
+        HazelcastCacheManager manager = spy(HazelcastCacheManager);
+        when(manager.createHazelcastInstance()).then(args -> hazelcastInstance)
 
         // when
         manager.init()
@@ -152,9 +138,9 @@ class HazelcastCacheManagerTest {
 
         // then
         assertFalse manager.implicitlyCreated
-        verify lifecycleService
-        verify hazelcastInstance
-        verify manager
+        verify(lifecycleService).shutdown()
+        verify(hazelcastInstance).getLifecycleService()
+        verify(manager).createHazelcastInstance()
     }
 
 }
diff --git a/support/jaxrs/pom.xml b/support/jaxrs/pom.xml
index c7ee487..20f6d0b 100644
--- a/support/jaxrs/pom.xml
+++ b/support/jaxrs/pom.xml
@@ -57,6 +57,12 @@
             <artifactId>jcl-over-slf4j</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.1</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy
index 8aa3c18..f42fbd6 100644
--- a/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy
+++ b/support/jaxrs/src/test/groovy/org/apache/shiro/web/jaxrs/ExceptionMapperTest.groovy
@@ -25,8 +25,8 @@ import org.junit.Test
 import javax.ws.rs.core.Response
 import javax.ws.rs.ext.RuntimeDelegate
 
-import static org.junit.Assert.*
-import static org.easymock.EasyMock.*
+import static org.junit.Assert.assertSame
+import static org.mockito.Mockito.*
 
 /**
  * Tests for {@link ExceptionMapper}.
@@ -43,22 +43,22 @@ class ExceptionMapperTest {
     }
 
     private void doTest(AuthorizationException exception , Response.StatusType expectedStatus) {
-        def runtimeDelegate = strictMock(RuntimeDelegate)
+        def runtimeDelegate = mock(RuntimeDelegate)
 
         RuntimeDelegate.setInstance(runtimeDelegate)
 
-        def responseBuilder = strictMock(Response.ResponseBuilder)
-        def response = strictMock(Response)
+        def responseBuilder = mock(Response.ResponseBuilder)
+        def response = mock(Response)
 
-        expect(runtimeDelegate.createResponseBuilder()).andReturn(responseBuilder).anyTimes()
-        expect(responseBuilder.status((Response.StatusType) expectedStatus)).andReturn(responseBuilder)
-        expect(responseBuilder.build()).andReturn(response)
-
-        replay runtimeDelegate, responseBuilder
+        when(runtimeDelegate.createResponseBuilder()).then(args -> responseBuilder)
+        when(responseBuilder.status((Response.StatusType) expectedStatus)).then(args -> responseBuilder)
+        when(responseBuilder.build()).then(args -> response)
 
         def responseResult = new ExceptionMapper().toResponse(exception)
         assertSame response, responseResult
 
-        verify runtimeDelegate, responseBuilder
+        verify(runtimeDelegate).createResponseBuilder()
+        verify(responseBuilder).status((Response.StatusType) expectedStatus)
+        verify(responseBuilder).build()
     }
 }
diff --git a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy
index b4224a1..297e1ce 100644
--- a/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy
+++ b/support/spring/src/test/groovy/org/apache/shiro/spring/config/ShiroEventBusAwareBeanPostProcessorTest.groovy
@@ -24,7 +24,7 @@ import org.apache.shiro.spring.ShiroEventBusBeanPostProcessor
 import org.junit.Assert
 import org.junit.Test
 
-import static org.easymock.EasyMock.*
+import static org.mockito.Mockito.mock
 
 /**
  * Tests for {@link org.apache.shiro.spring.ShiroEventBusBeanPostProcessor}
@@ -34,16 +34,13 @@ class ShiroEventBusAwareBeanPostProcessorTest {
     @Test
     void testPostConstructNonAware() {
 
-        def eventBus = createStrictMock(EventBus)
-        def bean = createStrictMock(Object)
-
-        replay eventBus, bean
+        def eventBus = mock(EventBus)
+        def bean = mock(Object)
 
         def postProcessor = new ShiroEventBusBeanPostProcessor(eventBus);
         def resultAfter = postProcessor.postProcessAfterInitialization(bean, "bean")
         def resultBefore = postProcessor.postProcessBeforeInitialization(bean, "bean")
 
-        verify eventBus, bean
         Assert.assertSame resultAfter, bean
         Assert.assertSame resultBefore, bean
     }
@@ -51,17 +48,14 @@ class ShiroEventBusAwareBeanPostProcessorTest {
     @Test
     void testPostConstructWithEventBusAware() {
 
-        def eventBus = createStrictMock(EventBus)
-        def bean = createStrictMock(EventBusAware)
+        def eventBus = mock(EventBus)
+        def bean = mock(EventBusAware)
         bean.eventBus = eventBus
 
-        replay eventBus, bean
-
         def postProcessor = new ShiroEventBusBeanPostProcessor(eventBus);
         def resultAfter = postProcessor.postProcessAfterInitialization(bean, "bean")
         def resultBefore = postProcessor.postProcessBeforeInitialization(bean, "bean")
 
-        verify eventBus, bean
         Assert.assertSame resultAfter, bean
         Assert.assertSame resultBefore, bean
     }
diff --git a/web/src/test/groovy/org/apache/shiro/web/servlet/ShiroHttpServletResponseTest.groovy b/web/src/test/groovy/org/apache/shiro/web/servlet/ShiroHttpServletResponseTest.groovy
index a26dca7..af23404 100644
--- a/web/src/test/groovy/org/apache/shiro/web/servlet/ShiroHttpServletResponseTest.groovy
+++ b/web/src/test/groovy/org/apache/shiro/web/servlet/ShiroHttpServletResponseTest.groovy
@@ -24,8 +24,8 @@ import javax.servlet.ServletContext
 import javax.servlet.http.HttpServletResponse
 import javax.servlet.http.HttpSession
 
-import static org.easymock.EasyMock.*
-import static org.junit.Assert.*
+import static org.junit.Assert.assertEquals
+import static org.mockito.Mockito.*
 
 /**
  * Unit tests for {@link ShiroHttpServletResponse}.
@@ -37,69 +37,70 @@ class ShiroHttpServletResponseTest {
     @Test
     void testEncodeURLNoSessionId() {
 
-        def servletContext = createStrictMock(ServletContext)
-        def httpServletResponse = createStrictMock(HttpServletResponse)
+        def servletContext = mock(ServletContext)
+        def httpServletResponse = mock(HttpServletResponse)
         def shiroHttpServletRequest = setupRequestMock()
-        expect(shiroHttpServletRequest.getSession(false)).andReturn(null)
-        expect(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).andReturn(true)
-        replay shiroHttpServletRequest, servletContext, httpServletResponse
+        when(shiroHttpServletRequest.getSession(false)).then(args -> null)
+        when(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).then(args -> true)
 
         def shiroHttpServletResponse = new ShiroHttpServletResponse(httpServletResponse, servletContext, shiroHttpServletRequest)
 
         assertEquals "/foobar", shiroHttpServletResponse.encodeURL("/foobar")
-        verify shiroHttpServletRequest, servletContext, httpServletResponse
+        verify(shiroHttpServletRequest).getSession(false)
+        verify(shiroHttpServletRequest).getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)
     }
 
     @Test
     void testEncodeURLSessionIdInURL() {
 
-        def servletContext = createStrictMock(ServletContext)
-        def httpServletResponse = createStrictMock(HttpServletResponse)
-        def session = createMock(HttpSession)
+        def servletContext = mock(ServletContext)
+        def httpServletResponse = mock(HttpServletResponse)
+        def session = mock(HttpSession)
         def shiroHttpServletRequest = setupRequestMock()
-        expect(session.getId()).andReturn(URL_SESSION_ID).anyTimes()
-        expect(shiroHttpServletRequest.getSession(false)).andReturn(session)
-        expect(shiroHttpServletRequest.getSession()).andReturn(session)
-        expect(shiroHttpServletRequest.isRequestedSessionIdFromCookie()).andReturn(false)
-        expect(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).andReturn(true)
-        replay shiroHttpServletRequest, servletContext, httpServletResponse, session
+        when(session.getId()).then(args -> URL_SESSION_ID)
+        when(shiroHttpServletRequest.getSession(false)).then(args -> session)
+        when(shiroHttpServletRequest.getSession()).then(args -> session)
+        when(shiroHttpServletRequest.isRequestedSessionIdFromCookie()).then(args -> false)
+        when(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).then(args -> true)
 
         def shiroHttpServletResponse = new ShiroHttpServletResponse(httpServletResponse, servletContext, shiroHttpServletRequest)
 
         assertEquals "/foobar;JSESSIONID=" + URL_SESSION_ID, shiroHttpServletResponse.encodeURL("/foobar")
-        verify shiroHttpServletRequest, servletContext, httpServletResponse, session
+        verify(shiroHttpServletRequest).getSession(false)
+        verify(shiroHttpServletRequest).getSession()
+        verify(shiroHttpServletRequest).isRequestedSessionIdFromCookie()
+        verify(shiroHttpServletRequest).getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)
+        verify(session, times(2)).getId()
     }
 
     @Test
     void testEncodeURLSessionIdInCookie() {
 
-        def servletContext = createStrictMock(ServletContext)
-        def httpServletResponse = createStrictMock(HttpServletResponse)
-        def session = createMock(HttpSession)
+        def servletContext = mock(ServletContext)
+        def httpServletResponse = mock(HttpServletResponse)
+        def session = mock(HttpSession)
         def shiroHttpServletRequest = setupRequestMock()
-        expect(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).andReturn(false)
-        replay shiroHttpServletRequest, servletContext, httpServletResponse, session
+        when(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).then(args -> false)
 
         def shiroHttpServletResponse = new ShiroHttpServletResponse(httpServletResponse, servletContext, shiroHttpServletRequest)
 
         assertEquals "/foobar", shiroHttpServletResponse.encodeURL("/foobar")
-        verify shiroHttpServletRequest, servletContext, httpServletResponse, session
+        verify(shiroHttpServletRequest).getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)
     }
 
     @Test
     void testEncodeURLSessionIdInWhenRewriteDisabled() {
 
-        def servletContext = createStrictMock(ServletContext)
-        def httpServletResponse = createStrictMock(HttpServletResponse)
-        def session = createMock(HttpSession)
+        def servletContext = mock(ServletContext)
+        def httpServletResponse = mock(HttpServletResponse)
+        def session = mock(HttpSession)
         def shiroHttpServletRequest = setupRequestMock()
-        expect(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).andReturn(false)
-        replay shiroHttpServletRequest, servletContext, httpServletResponse, session
+        when(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).then(args -> false)
 
         def shiroHttpServletResponse = new ShiroHttpServletResponse(httpServletResponse, servletContext, shiroHttpServletRequest)
 
         assertEquals "/foobar", shiroHttpServletResponse.encodeURL("/foobar")
-        verify shiroHttpServletRequest, servletContext, httpServletResponse, session
+        verify(shiroHttpServletRequest).getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)
     }
 
     /**
@@ -109,21 +110,24 @@ class ShiroHttpServletResponseTest {
     @Test
     void testEncodeURLSessionIdInWhenRewriteInvalid() {
 
-        def servletContext = createStrictMock(ServletContext)
-        def httpServletResponse = createStrictMock(HttpServletResponse)
-        def session = createMock(HttpSession)
+        def servletContext = mock(ServletContext)
+        def httpServletResponse = mock(HttpServletResponse)
+        def session = mock(HttpSession)
         def shiroHttpServletRequest = setupRequestMock()
-        expect(session.getId()).andReturn(URL_SESSION_ID).anyTimes()
-        expect(shiroHttpServletRequest.getSession(false)).andReturn(session)
-        expect(shiroHttpServletRequest.getSession()).andReturn(session)
-        expect(shiroHttpServletRequest.isRequestedSessionIdFromCookie()).andReturn(false)
-        expect(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).andReturn("something-else")
-        replay shiroHttpServletRequest, servletContext, httpServletResponse, session
+        when(session.getId()).then(args -> URL_SESSION_ID)
+        when(shiroHttpServletRequest.getSession(false)).then(args -> session)
+        when(shiroHttpServletRequest.getSession()).then(args -> session)
+        when(shiroHttpServletRequest.isRequestedSessionIdFromCookie()).then(args -> false)
+        when(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).then(args -> "something-else")
 
         def shiroHttpServletResponse = new ShiroHttpServletResponse(httpServletResponse, servletContext, shiroHttpServletRequest)
 
         assertEquals "/foobar;JSESSIONID=" + URL_SESSION_ID, shiroHttpServletResponse.encodeURL("/foobar")
-        verify shiroHttpServletRequest, servletContext, httpServletResponse, session
+        verify(shiroHttpServletRequest).getSession(false)
+        verify(shiroHttpServletRequest).getSession()
+        verify(shiroHttpServletRequest).isRequestedSessionIdFromCookie()
+        verify(shiroHttpServletRequest).getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)
+        verify(session, times(2)).getId()
     }
 
     /**
@@ -133,32 +137,34 @@ class ShiroHttpServletResponseTest {
     @Test
     void testEncodeURLSessionIdInWhenRewriteInvalidAndNull() {
 
-        def servletContext = createStrictMock(ServletContext)
-        def httpServletResponse = createStrictMock(HttpServletResponse)
-        def session = createMock(HttpSession)
+        def servletContext = mock(ServletContext)
+        def httpServletResponse = mock(HttpServletResponse)
+        def session = mock(HttpSession)
         def shiroHttpServletRequest = setupRequestMock()
-        expect(session.getId()).andReturn(URL_SESSION_ID).anyTimes()
-        expect(shiroHttpServletRequest.getSession(false)).andReturn(session)
-        expect(shiroHttpServletRequest.getSession()).andReturn(session)
-        expect(shiroHttpServletRequest.isRequestedSessionIdFromCookie()).andReturn(false)
-        expect(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).andReturn(null)
-        replay shiroHttpServletRequest, servletContext, httpServletResponse, session
+        when(session.getId()).then(args -> URL_SESSION_ID)
+        when(shiroHttpServletRequest.getSession(false)).then(args -> session)
+        when(shiroHttpServletRequest.getSession()).then(args -> session)
+        when(shiroHttpServletRequest.isRequestedSessionIdFromCookie()).then(args -> false)
+        when(shiroHttpServletRequest.getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)).then(args -> null)
 
         def shiroHttpServletResponse = new ShiroHttpServletResponse(httpServletResponse, servletContext, shiroHttpServletRequest)
 
         assertEquals "/foobar;JSESSIONID=" + URL_SESSION_ID, shiroHttpServletResponse.encodeURL("/foobar")
-        verify shiroHttpServletRequest, servletContext, httpServletResponse, session
+        verify(shiroHttpServletRequest).getSession(false)
+        verify(shiroHttpServletRequest).getSession()
+        verify(shiroHttpServletRequest).isRequestedSessionIdFromCookie()
+        verify(shiroHttpServletRequest).getAttribute(ShiroHttpServletRequest.SESSION_ID_URL_REWRITING_ENABLED)
+        verify(session, times(2)).getId()
     }
 
 
     private static ShiroHttpServletRequest setupRequestMock() {
-        def shiroHttpServletRequest = createMock(ShiroHttpServletRequest)
-
-        expect(shiroHttpServletRequest.getScheme()).andReturn("http").anyTimes()
-        expect(shiroHttpServletRequest.getServerName()).andReturn("localhost").anyTimes()
-        expect(shiroHttpServletRequest.getServerPort()).andReturn(8080).anyTimes()
-        expect(shiroHttpServletRequest.getContextPath()).andReturn("/").anyTimes()
+        def shiroHttpServletRequest = mock(ShiroHttpServletRequest)
 
+        when(shiroHttpServletRequest.getScheme()).then(args -> "http")
+        when(shiroHttpServletRequest.getServerName()).then(args -> "localhost")
+        when(shiroHttpServletRequest.getServerPort()).then(args -> 8080)
+        when(shiroHttpServletRequest.getContextPath()).then(args -> "/")
 
         return shiroHttpServletRequest
     }
diff --git a/web/src/test/java/org/apache/shiro/web/env/EnvironmentLoaderServiceTest.java b/web/src/test/java/org/apache/shiro/web/env/EnvironmentLoaderServiceTest.java
index 250370a..9a45d20 100644
--- a/web/src/test/java/org/apache/shiro/web/env/EnvironmentLoaderServiceTest.java
+++ b/web/src/test/java/org/apache/shiro/web/env/EnvironmentLoaderServiceTest.java
@@ -28,8 +28,14 @@ import java.util.Arrays;
 import java.util.List;
 
 import static org.easymock.EasyMock.expect;
-import static org.hamcrest.Matchers.*;
-import static org.hamcrest.MatcherAssert.*;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.sameInstance;
+import static org.hamcrest.Matchers.stringContainsInOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 /**
  * Tests for {@link EnvironmentLoader} which will use a ServiceLoader.
@@ -62,27 +68,21 @@ public class EnvironmentLoaderServiceTest {
 
         List<WebEnvironment> environmentList = Arrays.asList(new WebEnvironmentStub(), new WebEnvironmentStub());
 
-        ServletContext servletContext = EasyMock.mock(ServletContext.class);
-        expect(servletContext.getInitParameter(EnvironmentLoader.ENVIRONMENT_CLASS_PARAM)).andReturn(null);
-
-        EasyMock.replay(servletContext);
+        ServletContext servletContext = mock(ServletContext.class);
+        when(servletContext.getInitParameter(EnvironmentLoader.ENVIRONMENT_CLASS_PARAM)).then(args -> null);
 
-        final EnvironmentLoader environmentLoader = EasyMock.createMockBuilder(EnvironmentLoader.class)
-                .addMockedMethod("doLoadWebEnvironmentsFromServiceLoader")
-                .createMock();
-        EasyMock.expect(environmentLoader.doLoadWebEnvironmentsFromServiceLoader()).andReturn(environmentList.iterator());
-        EasyMock.replay(environmentLoader);
+        final EnvironmentLoader environmentLoader = spy(EnvironmentLoader.class);
+        when(environmentLoader.doLoadWebEnvironmentsFromServiceLoader()).then(args -> environmentList.iterator());
 
         try {
             environmentLoader.createEnvironment(servletContext);
             Assert.fail("Expected ConfigurationException to be thrown");
-        }
-        catch (ConfigurationException e) {
+        } catch (ConfigurationException e) {
             assertThat(e.getMessage(), stringContainsInOrder("zero or exactly one", "shiroEnvironmentClass"));
         }
 
-        EasyMock.verify(servletContext);
-        EasyMock.verify(environmentLoader);
+        verify(servletContext).getInitParameter(EnvironmentLoader.ENVIRONMENT_CLASS_PARAM);
+        verify(environmentLoader).doLoadWebEnvironmentsFromServiceLoader();
     }
 
     @Test()