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 FieldIt 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.