Komarro – A new interesting mock framework for Java

Mocking is a well-known and estabilished concept in our field of work as developers. There are a lot of frameworks for creating and setting up expectations on mock objects in all kinds of different languages. For me as a Java developer my introduction with mocking was through the EasyMock project. Due to the techincal limitations of this and other frameworks at the time me and a colleague founded PowerMock to make it possible to mock things such as new instance creation and static methods. Then Mockito came along and helped push forward the idea of a more state based approach to testing and mocking, focusing less on mocks and more on stubs. In my view this, seemingly quite small, API change has a profound impact on the way you think about mocking and writing tests. Komarro is the latest project to have caught my interest because of the ideas it present.

The problem

Mocking frameworks are founded on the principle that you should stub or mock interactions in the system. The focus of EasyMock and Mockito is method interactions. For example consider the follwing method:

Using the Mockito BDD API we can easily setup an expectation on the method interaction to the getPerson method like this:

Now for every call to personDao.getPerson with the social security number 123-45-6789 Mockito will return the person instance as defined in the expectation. Both EasyMock and Mockito verifies argument values in a natural Java style by using the equals() method. If you don’t care about an exact match between the socialSecurityNumber and the person being returned you can use something called argument matchers to loosen things up a bit:

Now it doesn’t matter what social security number you pass into the getPerson method, as long as it’s a String Mockito will return the person instace. PowerMock through its stubbing API provides a more generic approach that can be useful especially when testing legacy systems. You can instruct it to for all instances of the PersonDao class return the person instance when the getPerson method is invoked:

The drawback is of course that you loose the type-safety and PowerMock needs to do its byte-code manipulation magic. But what happens to your test if we change the method under test to this:

Will it still pass? No it won’t because of the explicit expectation on the method interaction with personDao.getPerson. But why shouldn’t it if it’s only the type of the interaction with the collaborator that has changed and no interaction is verified?

The Komarro solution

Komarro is a young mock framework based on Mockito. What it’s trying to show is that the explicit expectation on personDao.getPerson("123-45-6789") is irrelevant for the test and thus should be removed.

The intention of the Komarro initiative is to prove that unit testing can be performed without any knowledge of the collaborators implementation. Mockito’s when idiom is an implicit and unwanted verification of an interaction with a collaborator.

In Komarro you setup your expected interactions in a way not focusing on the instance method interaction but rather on the methods implicit input parameters:

What the expectation says is that it doesn’t matter from where (which repository) the person is requested as long as we will get zeus back. This also means that you create the mocks in a more implicit way. Let’s say that the getNumberOfChildrenBySSN method is defined in the PersonService class then you would create your mocks and test instance like this:

Here’s a full example:

Limitations

There are limitations to the Komarro approach. For example if you really are interested in the argument passed to the collaborator and need to return different results based on the argument value. There’s also a problem if multiple method interactions take the same argument type and have the same return type and you wish to differentiate between the two. The solution would be to revert back to vanilla Mockito for these kinds of expecations.

Conclusion

Komarro rasises some really interesting questions and ideas regarding interactions and the way we tend to look at them when writing tests. The ideas will need further exploration and evaluation but they seem to go in the right direction by providing a good way to trade test precision for durability when applicable. For more info have a look at the project web page.

5 Comments

  1. Like your post.

    another framework that comes to mind is the Spock framework, you should have a look (if you havent already :)). It forces you to use the given -> when -> then syntax. It depends on Groovy though, but that is just one jar extra on your classpath..

    http://code.google.com/p/spock/

    //Peace!

  2. I know about Spock but unfortunately I’ve never had the opportunity to try it out. I’m not scared of the Groovy dependency, I’m depending on Groovy in one of my other frameworks, REST Assured.

    Thanks for your comment!

  3. Interesting, though I’m not sure why you think Mockito is focused on “state based testing”?
    State based testing for me is creating a stub smart enough to store state, run the code under test and then test the end state against expected state.
    Mockito, in my view, helps you focus less on state but instead focus on interaction with collaborators.

    Regarding Komarro and “unit testing can be performed without any knowledge of the collaborators implementation” – sure, fine, but I’d say one does care about it’s contract.
    I surely see the overhead of mocking getPersonById(long) with Mockito compared to stubbing it with Komarro, and the fact that Komarro gives you something much closer to black box unit testing.

    Not sure I really had a point here, but thanks for sharing – sorry for spamming. :)

  4. Thanks for your comments.

    Let me clarify what I mean when I say that Mockito let’s you focus more on “state based verification” than “behavior based verification”. In my view Mockito is by default not a strict mocking framework. Mocks are specifications that should be setup before the test is actually executed and validated when the test is completed. EasyMock, by default, follows this quite closely. As I mentioned in the blog the difference may seem quite subtle but I believe that it shifts the focus of your tests away from the strict behavior based approach. With EasyMock you first enter “replay mode”, then you run your test and then you “verify” that the interactions with the mocks behaved accordingly. The way I see it Mockito let’s you move away from this strict replay-verify paradigm by focusing more on _stubs_. You simply stub the methods to return what’s needed. The point is that in many cases you don’t care that the particular method was even invoked on the mock. It just happens that in the current implementation that’s the collaborator used to achieve the end result. Mostly what you _really_ care about is that the method under test behaves as expected, meaning that it returns an expected result or change some state. How this happens (i.e. what interactions are needed to achieve the end result) is in many cases of no or at least of less importance. Komarro takes this idea one step further by not having you to even consider the method interaction of the “mock”. This is of course not always what you want. There are cases, just as you say, where you indeed want to verify a specific interaction. But I think the opposite is much more common.

    Regards,
    /Johan

  5. @Robert, I do not see how Spock is related to what Komarro does. Could you please explain?

Leave a Reply