Saturday, July 24, 2010

How to use custom argument matchers using PowerMock

We have come a long way and most likely this will be the last post in the series of how-to do stuff using PowerMock's (Mockito api) - Mocks on Steroid!

Some of the posts in the how-to series are more exotic then the others, but if you want to experience the real power of PowerMock, have a look at testing the UN-testable code.

In the previous post, we saw how we could use various argument matches, in situation when we don't know exactly what argument will be passed. Mockito already has a rich set of matchers but, if you think that is not enough we can write our own Matchers.

Why would you need them? Good question. In most cases the build in matchers are enough, but we might need custom matches when we want to make sure that a certain property of a certain class is set to a certain value.

Well did you understand that above sentence? No? Even I didn't understand that :)

As people say

Picture says a thousand words

my version of the same quote is

Code says everything

So lets look at the code under test.

Look at the argument passed to calculateChargeAmount method.  ServiceA's calculateChargeAmount passes a new instance of Calender to this method.

Of-course by now you already know how to test such a code. But since this post is about custom argument matchers, we will try to write a test for this method using the custom argument matcher.

But how do we write a custom argument matcher?

How will we test it - How do they do it!:

Well, turns out Mockito has a class called ArgumentMatcher. To create a custom matcher we extend the class ArgumentMatcher and override the matches method which returns a boolean.

If the matches method returns
  • true: means that the argument passed matches the criteria
  • false: means that the argument passed does not match the criteria
Along with this we need to use an argument matcher called argThat provided by Mockito. This argument matcher takes in an instance of our custom matcher, which will in-turn decide whether the argument passed matches our criteria.

Lets say in our example, we just want to make sure that the Calendar instance passed to the calculateChargeAmount method represents a date in the future.

This is how we could make use of the custom matcher in this case

Thats it folks! This is how we write custom argument matcher using Mockito.

It has been a pleasure doing this how-to series. I hope you guys have liked reading it as much as I have liked writing about it!
Have some Fun!