To mock or not to mock…final classes (finally)

Mockito has provided an ability to mock the final classes and many developers might have questions around this. Whether to mock the final classes or not?

I mean, there are already various options available, like PowerMock and others, which allow us to mock almost anything. But when it comes to Mockito, devs might be in dilemma.

Let me start with PowerMock first. This library provides devs a lot of flexibility in terms of what things you can mock, including private methods, static methods, finals, etc.

But I am of the opinion that these special weapons are provided just so that we can write unit tests for our legacy application, make them testable, gradually refactor them, and make sure that we don’t need PowerMock going ahead.

Whereas when Mockito is concerned, it seems to be more disciplined. One senior dev told me long ago that if you feel like you need to mock something and you can’t do it with Mockito, then probably you need to redesign the code. And I agree with this philosophy. I take this as a rule of thumb.

This reminds me of a story.

There were a few friends who were getting crazy about credit cards. They applied at a few banks but all of them rejected their applications (or what they offered was not so attractive to my friends). Then one of them got an idea. He exclaimed he would use his father’s documents to get a CC for himself.

One wise friend listened to the entire conversation, he concluded it by explaining to them that they shouldn’t do this. Though not illegal, there is a reason why banks have denied their request. Banks did not consider them creditworthy. Banks probably didn’t think they can either afford or manage a CC.

The moral is, if it feels like you are getting out of the way to get things mocked which shouldn’t be, then you shouldn’t proceed.

Having said that, the plugin used to mock final classes (org.mockito.plugins.MockMaker) is from the official org.mockito package. This doesn’t feel like going too much out of way. Moreover, the official Mockito documentation says that not being able to mock a final class is no more a limitation now (https://github.com/mockito/mockito/wiki/FAQ#what-are-the-limitations-of-mockito)

Digging further, I found that Mockito actually says that they have provided optional ability to mock the final class (https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2)

Mock the unmockable: opt-in mocking of final classes/methods

For a long time our users suffered a disbelief when Mockito refused to mock a final class. Mocking of final methods was even more problematic, causing surprising behavior of the framework and generating angry troubleshooting. The lack of mocking finals was a chief limitation of Mockito since its inception in 2007. The root cause was the lack of sufficient support in mock creation / bytecode generation. Until Rafael Winterhalter decided to fix the problem and provide opt-in implementation in Mockito 2.1.0. In the releases, Mockito team will make mocking the unmockable completely seamless, greatly improving developer experience.

An important thing to note here is that the mocking of final classes was not supported not because it’s “not a good thing to do” or it’s “anti-pattern”, it was because they did “not have sufficient support”.

If it seems like a lot of work in not mocking final classes and the benefits are a few if any, then simply mocking them won’t harm. Having said that, decide case-by-case till you gain confidence.

Happy coding!

Leave a Reply

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