Why is wide usage of PowerMock problematic

There are Java constructs well known for their testability issues:

  • Private methods
  • Static methods
  • Constuctors
  • Final methods or classes

Skilled Java developer following TDD tries to minimize their testability impacts. Don’t want to dive into techniques to enhance testability. They are explained well on Misko Hevery’s blog.

Some developers argue that we have frameworks today (like PowerMock or JMockIt) that are able mock these testability killers. And it’s true. So should we throw factory methods to bin and start using static or singleton classes widely? The answer is NO. Reason is in Java language nature. There isn’t way how to mock mentioned constructs using Java features like inheritance, polymorphism or reflection. Byte-code manipulation is needed. And that is the problem.

Here are some facts about PowerMock:

  • It is using Javassist library for byte-code manipulation
  • It took 1.5 years to make PowerMock + Javaassist compatible with Java7 since its introduction. Here is note from PowerMock change log:
Change log 1.5 (2012-12-04)
---------------------------
Upgraded to Javassist 3.17.1-GA, this means that PowerMock works in Java 7!

I tried to use PowerMock and JMockIt to test some legacy code. The result weren’t acceptable for me. Sometimes there were some strange crashes or clash with JaCoCo test coverage tool (have to say that I didn’t give JMockIt deep chance and abandoned on it immediately after first problems). At the end I always decided to change the production code to enhance testability and use plain Mockito.

If it would be up to me I would exclude byte-code manipulation testing frameworks from technology stack completely. Java8 is coming soon and potential migration of unit tests can be a big problem if it is used widely. It would be ridiculous to wait 1.5 years for Java8 update because of testing framework.

I respect PowerMock and JMockIt projects and people behind them. They are sometimes valuable in cases when you have to deal with legacy code or third party libraries.

3 thoughts on “Why is wide usage of PowerMock problematic

  1. This article makes no sense in light of current state of the art in Java-based mocking tools. JMockit works just fine with Java 7 and Java 8.

    As for “using static or singleton classes widely”, I don’t see the connection. Care to explain?

    Personally, I need the ability to mock final classes/methods, constructors, and the occasional static method, in order to keep production code clean, simple, and object-oriented. Not having these abilities in the mocking tool forces the code under test to become more complex, as workarounds need to be provided to avoid the arbitrary limitations of more restrictive mocking APIs.

    1. This article comes from my frustration when I was trying to mock these constructs. I was having a lot of weird issues in my tests. They were gone, when I excluded mocking frameworks that use byte-code manipulation.
      Most of problems were with PowerMock.
      I rather design my code to use constructs mockable by plain Mockito now.

      As creator of JMockIt framework (that highly depends on byte-code manipulation), you clearly have opposite opinion. I respect that.

  2. Yet another valid opinion that essentially boils down to: javassist (or a similar tool) should ship with java…

    it stands in the way of so many nice tools for java… (just don’t ship production code that does run-time byte-code manipulation… *sigh*)

Leave a Reply to Lubos Krnac Cancel reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.