• WORK
  • PEOPLE
  • ABOUT
  • BLOG
  • Blog
  • News
  • Events
  • Presentations
  • How to Mock Final Classes in Unit Tests

    By Neil Buesing on Mar. 15 2012

    Mocking has become a key component to writing effective unit-tests. It is a very useful strategy to write focused tests. Mocking frameworks make it easy to write test, but they have their limitations. Both Mockito and EasyMock cannot mock classes (or methods) that are final. This article will show you how to mock such classes while continuing to use your favorite mocking framework (Mockito for the sake of this article).

    In a future article, I will extend this strategy to writing unit tests for Google Web Toolkit (GWT) without the need of the GWTTestCase.

    Goal

    Provide a framework that can mock final classes, while using an existing mocking framework. For this, I have implemented PreMock.

    Alternate Solutions

    1. Refactor – Refactoring the code you need to mock (so it can be mocked) can be the best solution. Extracting an interface, making a method not final, etc. are all valid options. However, it is not always practical, the class you need to mock could be within a 3rd party library. Also, rewriting a class to make it easier to test, may expose more to your API than desired. Furthermore, I am not a fan of adding boiler plate wrapping classes, just to support unit testing (if it can be avoided). The less code you need to write, the easier it is to maintain.
    2. Don’t Mock – Mocking isn’t always necessary, and sometimes it is not the best choice. For example, instead of mocking your persistence tier for testing your services, provide a persistence tier that can be used within unit tests. See Unit Testing Your Persistence Tier Code.
    3. Powermock – There is already an open-source library out there that provides a way to mock final classes. I had difficultlies getting it configured for the tests I needed. Also, it could not be extended to create the desired tests for GWT (this is something I plan on covering in a future article).

    Strategy

    Alter the class, with byte code manipulation, as it is being loaded by a custom class loader. During loading of the class remove the final modifier. When the class is loaded to Mockito it will be a non-final class.

    Difficulties

    • Get the class loader in place so that any class referenced in the unit test will use by the class loader; allow for our unit-test to be written like any other unit test.
    • Alter the byte code of the java class when it is being loaded.
    • Make sure that classes that should not be modified, are not modified.

    Technologies

    1. Java 6 – I’m sure Java 5 and Java 7 would work, provided the versions of JUnit, Mockito, and Javassist also worked with the desired version of Java.
    2. JUnit 4.10 – Junit has gone over some major tranformations in regards to the test runner. Mockito, Spring, and others frameworks provide test runners for making writing unit tests easier. Here we will write a test runner than will allow us to mock those classes and methods that Mockito and Easymock cannot test. Versions since 4.8.2 should work, and I expect versions since 4.7 will also work. The runner changed between version 4.6 and 4.7, so I believe 4.6 and earlier versions of JUnit will not work.
    3. Mockito 1.9.0 – I am sure this can be applied to older versions of Mockito and other versions of Easymock. While I have used EasyMock longer, I find Mockito easier to use. Mockito has its own JUnit test runner; it will be incorporated into the test runner described here, since I don’t want to loose it’s functionality. I have also tested against version 1.8.5
    4. Javassist 3.15 – Bytecode manipulation is the key component to removing the final modifier. I’m sure ASM would also work, but personally, I like Javassist. I did some testing against an older version of 3.4, and it worked fine.

    Solution

    This solution can be found on github as an Eclipse Project, see PreMock. Only 3 classes are needed for PreMock, and they are:

    PreMock
    This annotation will be used within the JUnit test to determine which classes can be pre-mocked. This will insure we do not alter a class unexpectedly; only the unit test and classes listed here are loaded by the custom class loader.

    PreMockClassLoader
    Using javassist, this classloader will do byte-code manipulation to remove the annoying final modifier. While the use of javassist here is very light, when I expand on PreMock for GWT testing, javassist will be utilized more. This class-loader will pass all classes to the parent class loader, except for the unit test and the classes annotated in @PreMock.

    PreMockJUnit4ClassRunner
    JUnit does not provide a way to change the class loader, so this ParentRunner does the trick. It reloads the unit test with our custom class loader, and then swaps it in. Once JUnit uses the custom class loader for our test class, we are all set. Please read the comments in the code to understand how this swap takes place. Also, the code provided in the Mockito Test Runner is included, since you can only have one Parent Runner. Mockito’s Runner is what allows the @Mock and @InjectMocks to work.

    Example
    Here is a unit test that successfully tests a final class with a final method. To see it fail due a final class, simply replace PreMock in the @RunsWith with Mockito’s.

    Summary

    I hope that this can make it easier for you to write unit tests. The easier they are to write, the more likely developers will write them.

    The entire source of this blog is accessible from Github at https://github.com/nbuesing/opiblog-premock and is a complete Eclipse project.

    In a future article I will extend what I started here to write unit-test for GWT that does not need the GWTTestCase.

    6 Responses to How to Mock Final Classes in Unit Tests

    1. Roger Glover says:
      March 17, 2012 at 7:55 pm

      Or, um, just use PowerMock or gMock?

      Reply
    2. Roger Glover says:
      March 17, 2012 at 8:12 pm

      Sorry Neil, I see now that you addressed that. I should not skim quite so lightly. Eagerly awaiting your explanation of why PowerMock was inadequate for your needs.

      I’m using gMock on my current project. The mocking code and playback almost writes itself, and static, final, and private mocking are trivial.

      The problem gMock has that PowerMock doesn’t is that these special encapsulation-breaking mocking features only work when the method invocation is in Groovy code. All other mocking features but these work equally well in Groovy and Java code. Maybe a Groovy-equivalent of your javassist-based code could be helpful to me after all.

      Reply
    3. sudr says:
      March 18, 2012 at 7:57 am

      JMockIt does a great job of this. It combines the capablities of Mockito and Powermock into one library and goes further.

      Reply
    4. Neil Buesing says:
      March 19, 2012 at 8:01 am

      With powermock it seems you have to constantly worry about versions of mockito and junit for any upgrade.

      see: http://code.google.com/p/powermock/wiki/MockitoUsage13

      Also, currently release doesn’t support JUnit 4.10 (see next release section in –
      http://powermock.googlecode.com/svn/trunk/changelog.txt)

      But my main issue was getting JUnit, Mockito, Powermock, and GWT all working together. I’m sure it was something on my end, but the problem that I was trying to solve here seemed trivial and power mock seemed rather heavy. It only took me 3 classes (and one is trivial) to do this, and now I don’t have to worry about the upgrade path of Powermock with Junit and Mockito.

      Part of me didn’t feel like writing this article up, due to other options out there. However, I feel this a good reference for using byte code manipulation with a custom class loader. It also shows how to trick-out junit to make this happen (and gives developers a better understanding of what PowerMock must be doing).

      Reply
    5. amit says:
      March 20, 2012 at 6:41 pm

      As stated in other comments as well we can use PowerMock which is extension of
      mockito. Here is a blog that I have put together on the same topic.. http://www.spinachsoftware.com/blog/?p=19

      Reply
    6. Blaise says:
      May 1, 2013 at 12:48 pm

      I Thank you very much for your codes Neil,
      but i have a problem using it. I’m using Mockito and I want to mock the call on a static method like this(LicenseManager.getInstance()).
      I declared class LicenseManager in the annotation @PreMock, using annotation @RunWith(PreMockJUnit4ClassRunner.class) and i use the following code in my test method:

      PowerMockito.mockStatic(LicenseManager.class);
      LicenseManager instance = Mockito.mock(LicenseManager.class);
      Mockito.when(LicenseManager.getInstance()).thenReturn(instance)

      But, I realize that the body of method getInstance is still executed. Can you help me please.
      I’ve searched on google for several days and your method seems to be the best to mock final class. please can some body help me to use it with static method?

      Reply

    Leave a Reply Cancel reply

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

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

  • Case Studies
  • Java
  • Grails
  • Mobile
  • Approach
  • People
  • Blog
  • Community
  • About
  • Careers
  • Leadership Team
  • Contact
  • Corporate Headquarters
    Object Partners, Inc.
    Butler Square, Suite 302A
    100 North Sixth Street
    Minneapolis, MN 55403
    (612) 746-1580