Posts

Mocking in Java: why mocking, why not mocking, mocking also those awful private static methods

Unit tests: there are people out there surviving without, by in many cases you wan to have this life insurance. Something to protect you from slipping an error, something to accompany your software also when you will have long forgotten it and someone else will have to figure out how to maintain that legacy thing.

Why Mocking

If you want (need?) to write unit tests, by definition they have to test in isolation the behavior of a small unit (typically a class). The behavior of the tested method should not depend on the behavior of some other class because:

  • the other classes will change (impacting our test),
  • because the other class is not predictable (random generator, user input),
  • because it depends on external elements (network, databases,other processes),
  • because the other classes could require a complex initialization, and you do not want to do that

The unit test should reply to the question:

Does my unit work in an ideal world, surrounded by extremely nice and well behaving neighbours?

Mocks provide that ideal world. You can try the luck of your system in the ideal world using other kinds of tests (like integration tests).

The argument “mocking is a bad thing”

Some people argue that you should not use mocks, because you should build your systems in such a way that make mocking not necessary.

I think this is partially true: if a system is well designed, with testability in mind from day 0, probably it will require much less mocking than otherwise. However you will still need mocking for three reasons:

  • you will inherit systems which either have no tests or have a low coverage. If tests are added as an afterthought the system is not designed to be testable and you will end up using a lot of mocking
  • it is true that in most situation you can avoid using mocking if you build your system using a lot of interfaces and dependency injection. However it means in most cases to use a fair amount of overengineering. You will end up having all over the places interfaces like FooBarable, BarFooator, and then classes like DummyFooBarable, HttpFooBarable, etc. Good, now you can avoid mocking but your system is became one of the reasons why other programmers laugh at Java code
  • sometimes your unit is a method, not a class, so you want to mock the rest of the class (partial mocking). Suppose you want to test method foo of class Foo. This method invoke bar and baz of the same class. If these methods interact with a lot of other classes (Bazzator, Bazzinga, BazLoader) it could be easy to just mock the methods bar and baz instead of mocking these other classes. Another advantage is that it make your tests more readable: you could write something like when this.bar() return 3 than this.foo() should return false instead of building a complex test to create the conditions under which this.bar() return 3

So, yes, you should not be mocking all the times, but many times you do not have an alternative and in some cases the alternative is way worse.

Mocking basics

Ok, let’s start by specifying our dependencies. We will use both Mockito and Easymock together with PowerMock for extra power. PowerMock complements both of Mockito and Easymock.

My scenario

I had to work with a legacy application: you know, the kind of application that one wants to touch even with a pole, the one with all the original authors disappeared (deported for their crimes?). You get the picture. Now we had to do a tiny change to this application and then run away like hell. Given we are good professionals we wanted to write a test: the problem was that our change was inside a very large method which was private and static. The method is named dealsToDisplay. Given it is private and static we invoke it through reflection (see invokeDealsToDisplay()). The actual tests are in dealsToDisplayNoBlacklistingTest, dealsToDisplaySomeBlacklistingTest, dealsToDisplayCompleteBlacklistingTest. All the rest is mocking and plumbing.

Mocking static methods

In my scenario I had to:

  • invoke a private static method
  • mock several static methods

The former is easy, you just have to use reflection:

We start by finding the method and we set is accessible (setting back the previous value when we are done). At this point we can invoke it. Nice. Sort of.

To mock static methods we have instead to use PowerMock which does the trick by using a custom Classloader and doing bytecode rewriting on the fly. Yes, it does not sound safe. No, there are no alternatives that I am aware of.

So we need to do a few things, first of all we have to instruct PowerMock to take care of loading the class through its Classloader:

Then we have to declare which methods we intend to mock:

Finally we mock them, specifying what result do we want when they are invoked:

Conclusions

Our solution required a considerable amount of pluming and mocking, mocking and plumbing, to test a very limited functionality. While we are happy with the result and have reasonable confidence with this not destroy that old piece of code, it is clear that it is not an ideal scenario. But sometimes you have to  do what you gotta do.

Bonus: mocking singletons

A common issue is the necessity of mocking singletons. While you can write your own recipe reusing the code presented in this post, you can also take a look at this post:

Mocking a singleton with EasyMock and PowerMock

Happy mocking!

P.S. If you have suggestions, or corrections please let me know!

Update

Steve Bennett wrote some interesting comments about this post, it is worthy taking a look on Steve Bennett’s blog.