EasyMock supports creating partial mock, where we can specify the methods that will be mocked. If any other method is called, object real method will get invoked.
EasyMock Partial Mock Example
Let’s say we have a utility class defined as:
1 2 3 4 5 6 7 8 9 10 11 |
package com.journaldev.utils; public class StringUtils { public void print(String s) { System.out.println(s); } public String toUpperCase(String s) { return s.toUpperCase(); } } |
We want to mock toUpperCase()
method but not print()
method. We can use partialMockBuilder()
method to achieve this. We will also have to use addMockedMethod()
to provide the list of methods to be mocked.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.journaldev.easymock; import static org.easymock.EasyMock.*; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; import com.journaldev.utils.StringUtils; public class EasyMockPartialMockingExample { @Test public void test() { StringUtils mock = partialMockBuilder(StringUtils.class) .addMockedMethod("toUpperCase").createMock(); expect(mock.toUpperCase("java")).andReturn("JAVA"); replay(mock); //real method will be called, check the console mock.print("java"); //testing mocked method assertEquals("JAVA", mock.toUpperCase("java")); verify(mock); } } |
If you want to mock multiple methods in the partial mock, use addMockedMethods()
with the method names as argument.
EasyMock Partial Mock Constructor
We can call a class constructor too while creating the partial mock. This is useful when the real methods are using some properties set through the constructor.
For calling a partial mock constructor, we can use withConstructor()
and withArgs()
method. There are multiple overloaded withConstructor() methods, chose one that fits your class constructor requirements.
Let’s say we have a Data class defined as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Data { private String message; private String encodedMsg; public Data(String msg) { this.message = msg; } public void print() { System.out.println("Message is: "+this.message); } public String encode() { this.encodedMsg = Base64.getEncoder().encodeToString(this.message.getBytes()); return encodedMsg; } public String decode() { return String.valueOf(Base64.getDecoder().decode(encodedMsg)); } } |
We want to mock only decode()
method. But since print() and encode() methods are using object property being set through the constructor, we will have to create partial mock and call its constructor too.
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 |
package com.journaldev.easymock; import static org.easymock.EasyMock.*; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.Base64; import org.junit.jupiter.api.Test; public class EasyMockPartialMockConstructorExample { @Test public void test() { Data mock = partialMockBuilder(Data.class) .withConstructor(String.class) .withArgs("Hello") .addMockedMethods("decode") .createMock(); //calling real methods mock.print(); String encodedMessage = mock.encode(); System.out.println(encodedMessage); assertEquals(Base64.getEncoder().encodeToString("Hello".getBytes()), mock.encode()); //mock some behaviors expect(mock.decode()).andReturn("Hello"); replay(mock); assertEquals("Hello", mock.decode()); verify(mock); } } |
Summary
EasyMock partial mock is helpful when we are interested in testing only a few methods of the class. It’s very similar to creating partial mock in Mockito using Mockito Spy.