In a previous post, I talked about what Mocking is, and why you might want to use it. Now that we think we want to mock our objects, where do we start?
There are plenty of libraries available to allow you to create mock versions of your objects, and if you don’t like any of them, you can always create your own. For many years, my team created our own mock objects rather than using libraries simply because we felt the libraries didn’t offer some of the things we wanted. (I will be focusing on Java).
Rolling your own
Creating your own mocks is very straightforward, however it does add some additional overhead that may make your code a little harder for newcomers to understand.
When creating your own mocks, every class that you create that is going to interact with other classes (which is pretty much all of them) needs an interface*. This will allow us to create our production class, as well as the mock version of our class. So, it will look something like this:
Class <<interface>> ProductionClass implements Class MockClass implements Class
Then, inside our MockClass, we create fake versions of the methods that can capture arguments passed in, additional methods that aren’t part of the interface to set return values, set up methods to throw exceptions, and to get information back out about method calls (like whether it was called, the arguments passed in, etc).
The benefits to creating your own mocks are many. Creating your own mocks is very simple, you just have to create an interface and implement that, everything else is straight up Java. Because you have complete control over the mock objects, you have lots of flexibility. Another great advantage I have seen is that you can set your objects up to have default return values (like empty lists instead of null), which is very beneficial. (When using Mockito, for instance, if you don’t tell a method what to return, it will return null, so you must set it up every time you use it.)
Since you are writing your own mock classes, you can set breakpoints inside the mock object itself, and inspect the state of the mock object easily (this is not true of Mockito). Lastly, I think creating your own mock objects at some point in your career is a a good exercise as it gives you a firm understanding of mocks and how they work.
The downside is that there is a fair amount of additional overhead to working this way. You have a bunch of interfaces that are only useful because you need to create mock objects, and a whole bunch of mock classes that you need to write by hand. While both of these things are easy to create, it is additional overhead that many teams are unwilling to take on.
* Creating interfaces for your objects is very easy, but it can cause annoyances with naming. Since most of the objects we create from day to day don’t have variations, and wouldn’t strictly require an interface, you are left with the conundrum of what to name the interface and what to name the implementation class. We went with the convention of naming our implementation classes with the postfix of Impl. Not the prettiest solution, but it worked for us.
Mockito (as a surrogate for mocking libraries)
I will admit that the only mocking framework that I have tried is Mockito, so some of my issues with mocking things using a framework are likely to be biased.
The biggest drawback I can see to using a framework to do your mocking is that there is a learning curve (and for Mockito it is a little steep), whereas when you roll your own mocks it is really quite simple. I think there is a slight sacrifice in readability when using a mocking framework (or maybe it’s just mockito) until you are used to it’s syntax. For me, Mockito seems to have several different modules mashed together to make a framework, and each has it’s own way of thinking about the problem, making the syntax less cohesive than one would like.
There are several nice benefits to using a framework. First of all, you don’t have to create a bunch of interfaces just to mock out your objects, so there is less code lying around and it is a little easier to navigate.
Secondly, there is a lot of pre-built functionality in the frameworks so you don’t have to have a bunch of near duplicated code. When you look at hand-created mocks, you will see a lot of similarities between the mock objects which should really be generalized. The pre-built functionality ends up meaning that you have a lot less code to maintain, which is huge.
My recommendation would be that you find a small personal project and write your own mocks with that project just to get a deeper understanding of mocks and how you would do some of the things that a framework will provide you.
But, overall I would recommend using a mocking framework in your production code because it will actually make your life easier in the long run (though the going may be a little rough at first). You will have less code to maintain and you won’t have to worry about debugging your mock objects (though that is usually not an issue).