One of the limitations of EasyMock is that it can’t mock final methods and final classes. However, we can use PowerMock EasyMock extension to mock static methods.
EasyMock Final Method and Class using PowerMock
PowerMock is divided into multiple modules to support JUnit and TestNG testing framework. Similarly, there are modules to extend EasyMock and Mockito mocking frameworks.
I will provide an example to mock final method inside a final class using PowerMock on both JUnit 4 and TestNG frameworks. So we need to import the following artifacts.
- powermock-module-junit4
- powermock-module-testng
- powermock-api-easymock
- junit, testng and easymock for obvious reasons.
I am not using JUnit 5 because PowerMock doesn’t support it yet. I am using the following versions for my examples.
1 2 3 4 5 6 7 |
<junit4.version>4.12</junit4.version> <testng.version>6.14.3</testng.version> <powermock.version>2.0.0-beta.5</powermock.version> <java.version>10</java.version> <easymock.version>3.6</easymock.version> |
JUnit PowerMock EasyMock Final Method Example
- First step is to annotate test class with
@RunWith(PowerMockRunner.class)
annotation. - Next step is to specify the classes to prepare for testing using PowerMock, for example
@PrepareForTest(Data.class)
. This has to be done at the class level and we can use itsfullyQualifiedNames
to specify multiple classes and packages. - In the test method, use
PowerMock.createMock()
method to mock the final class. - Stub the behaviors using
EasyMock.expect()
method. - Use
PowerMock.replay()
to finalize the mock object and its behavior setup. - Use JUnit 4 asserts to test the behaviors.
- Use
PowerMock.verify()
to verify that all the stubbed final methods were called.
Let’s say we have a final class as:
1 2 3 4 5 6 7 |
final class Data { final String reverse(String s) { return new StringBuffer(s).reverse().toString(); } } |
Here is the JUnit test to mock the final class and its final method and test it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.journaldev.easymock.powermock.finalmethod; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import static org.powermock.api.easymock.PowerMock.*; import static org.easymock.EasyMock.expect; import static org.junit.Assert.assertEquals; import static org.easymock.EasyMock.anyString; @RunWith(PowerMockRunner.class) @PrepareForTest(Data.class) public class JUnit4PowerMockEasyMockFinalExample { @Test public void test_final_method_class() { //PowerMock.createMock() Data mock = createMock(Data.class); expect(mock.reverse("CAT")).andReturn("TAC"); expect(mock.reverse(anyString())).andReturn("INVALID"); //PowerMock.replay() replay(mock); assertEquals("TAC", mock.reverse("CAT")); assertEquals("INVALID", mock.reverse("Java")); //PowerMock.verify() verify(mock); } } |
TestNG PowerMock EasyMock Final Method Example
If you want to use TestNG instead of JUnit-4, then make sure your test class extends PowerMockTestCase
class. Also remove the @RunWith
annotation. Make necessary changes to other annotations and use TestNG assert methods.
Below class uses TestNG along with PowerMock to mock final methods using EasyMock.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
package com.journaldev.easymock.powermock.finalmethod; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.testng.PowerMockTestCase; import org.testng.annotations.Test; import static org.powermock.api.easymock.PowerMock.*; import static org.testng.Assert.assertEquals; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.anyString; @PrepareForTest(Data1.class) public class TestNGPowerMockEasyMockFinalExample extends PowerMockTestCase{ @Test public void test_final_method_class() { //PowerMock.createMock() Data1 mock = createMock(Data1.class); expect(mock.reverse("CAT")).andReturn("TAC"); expect(mock.reverse(anyString())).andReturn("INVALID"); //PowerMock.replay() replay(mock); assertEquals("TAC", mock.reverse("CAT")); assertEquals("INVALID", mock.reverse("Java")); //PowerMock.verify() verify(mock); } } final class Data1 { final String reverse(String s) { return new StringBuffer(s).reverse().toString(); } } |
Summary
PowerMock is a great extension to EasyMock and Mockito mocking frameworks. It helps us to extend our test cases to cover final classes and final methods too.