Mocking final classes with Mockito and JavaAssist

Sometime you need to mock final classes. I never got why people will write final classes, but since they do – and we need to mock those classes – here is a nice solution. I’m using JavaAssist here, which is a framework that can manipulate classes at run time.

Note that this code must run before anything else in your unit tests – Constructor, @Before, @BeforeClass, @PostConstruct (if you use Spring) annotations will not do. This has to be a static block on your unit test class (or its base). Otherwise, your final class will already be loaded, and you’ll get weird exceptions like “attempted duplicate class” LinkageError.
First of all – add JavaAssist to your project. I use gradle, so:

testCompile group: 'org.javassist', name: 'javassist', version: '3.22.0-GA'

Note the testCompile – we only use Mockito and JavaAssist on our test classes, so no need to bundle it in your code.
Then, write a static block on your unit test class (or it’s base class. Will work either way)

    static {
        try {
            ClassPool cp = ClassPool.getDefault();
            CtClass cc = cp.get("fully qualified class name");
            cc.defrost();
            int clzModifiers = cc.getModifiers();
            clzModifiers = javassist.Modifier.clear(clzModifiers, Modifier.FINAL);
            cc.setModifiers(clzModifiers);
            cc.toClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

And walla. You can now use @MockBean, Mockito.mock or any other method you use to mock classes.
Enjoy.

Leave a Reply

Your email address will not be published. Required fields are marked *