Mock Java final class and override a method
In this tutorial, we will see how we can mock a final class using mockito. We will do a demo on JDK final class java.lang.reflect.Field
:
public final class Field
It is a fundamental Java class, used a lot in reflection code logics. We will override a method and forward the rest.
First, import Mockito 5. Add this dependency to your pom.xml
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.14.2</version>
</dependency>
Then let’s call the mock function, and provide our own answer. The Mockito function signature is:
static <T> T mock(Class<T> classToMock, Answer answer)
In the Answer
object, we can get the arguments via .getRawArguments()
and the Method
class using .getMethod()
.
Now, let’s create an Integer
field, and modify it’s .getType()
value to String
. We will leave other methods, such as .getName()
, unchanged.
Class A
with field Integer i
:
static class A {
Integer i;
}
Then, call the .mock()
function on the Field
instance of i
:
var field = A.class.getDeclaredField("i");
// mock field, and override getType() method
var fieldMocked = mock(Field.class, invocation -> {
var args = invocation.getRawArguments();
var m = invocation.getMethod();
m.setAccessible(true);
var name = m.getName();
// override getType() method
if (name.equals("getType"))
return String.class;
// forward all other method calls
return m.invoke(field, args);
});
We can add test assertions to check that getType()
is overridden properly and that .getName()
is left unchanged:
assertEquals(Integer.class, field.getType());
assertEquals("i", field.getName());
assertEquals(String.class, fieldMocked.getType());
assertEquals("i", fieldMocked.getName());
You can see the full working code in my Github repo. You may leave a question in the issues if you need.