Showing posts with label powermock. Show all posts
Showing posts with label powermock. Show all posts

Thursday, October 31, 2013

An Author Is Born - Instant Mock Testing with PowerMock

After quite a few long nights and working weekends, finally the book written by me on PowerMock is published and is available to be bought here, here and here.  It’s available in Paperback and almost all major eBook format.

It’s a book for anyone who wants to learn/master mock testing with PowerMock using the Mockito API.  If you are keen on learning a mocking framework that can mock almost any class, PowerMock is the way to go.  Starting with a basic example of how to create a mock and verify a method invocation, Instant Mock Testing with PowerMock demonstrates various features of PowerMock using clear, practical, step-by-step recipes. 

Moving on from the basics, you will learn how to write unit tests for static, final, and private methods, and write flexible unit tests using argument matchers. Following on from this, you will also learn how to invoke real implementation of some methods and mock only a few methods of a class, using partial mocks or spies. This book will teach you all tricks of the trade and enable you to write good unit tests for a wide range of scenarios.

The Back and Front Cover of the Book
Any feedback would be greatly appreciated (if you want to buy it, please let me know, I can get some deep – pun intended :) – discounts using the Author discount code).

I would like to thank Jayway and the Java Community for a great mocking framework.
I cannot imagine finishing this book without the dedication and support of my loving family, who put up with long nights and working weekends for far longer than I had initially planned for.  

Lastly, I would also want to thank PACKT Publishing and their entire team, without whose efforts this book would have been impossible.  It would be inappropriate on my part, if I didn't extend my special thanks to Govindan, Sherin and Aparna from PACKT Publishing.
I would conclude this post with the preface of the book for your reference:

 Preface
PowerMock is an open source mocking library for the Java world. It extends the existing mocking frameworks such as EasyMocks (see http://www.easymock.org/) and Mockito (see http://code.google.com/p/mockito/) to add even more powerful features to them.
PowerMock was founded by Jayway (see http://www.jayway.com/) and is hosted on Google Code (see http://code.google.com/p/powermock/).
It has a vibrant community with a lot of contributors. Conscious efforts have been made to ensure that PowerMock does not reinvent the wheel. It only extends existing mocking frameworks and adds features that are missing from them. The end result is a mocking library that is powerful and is a pleasure to use.
Sometimes a good design might have to be tweaked to enable testability. For example, use of final classes or methods should be avoided, private methods might need to open up a bit by making them package visible or protected, and use of static methods should be avoided at all costs. Sometimes these decisions might be valid, but if they are taken only because of limitations in existing mocking frameworks, they are incorrect. PowerMock tries to solve this problem. It enables us to write unit tests for almost any situation.
What this book covers
Saying Hello World! (Simple) explains a basic mocking example using PowerMock. It will help us get familiarized with basic mocking and verification syntax.
Getting and installing PowerMock (Simple) demonstrates the steps for setting up PowerMock using IntelliJ IDEA and Eclipse. It also briefly describes other ways of setting up the PowerMock environment.
Mocking static methods (Simple) shows how effortlessly we can mock static methods with PowerMock. Most of the mocking frameworks have trouble mocking static methods. But for Power Mock, it’s just another day at work.
Verifying method invocation (Simple) explains various ways in which we can verify a certain method invocation. Verification is an indispensable part of unit testing.  
Mocking final classes or methods (Simple) covers how easily we can mock final classes or methods. Mocking final classes or methods is something that most mocking frameworks struggle with. Because of this restriction, sometimes a good design is sacrificed.
Mocking constructors (Medium) introduces the art of mocking constructors. Is a class doing too much in its constructor? With PowerMock, we can mock the constructor and peacefully write tests for our own code.
Understanding argument matchers (Medium) demonstrates how to write flexible unit tests using argument matchers. Only verifying that a certain method was invoked is a job half done. Asserting that it was invoked with correct parameters is equally important.
Understanding the Answer interface (Advanced) demonstrates the use of the Answer interface, using which we can create some unusual mocking strategies. Sometimes mocking requirements are extremely complex, which makes it impractical to create mocks in the traditional way. The Answer interface can be used for such cases.
Partial mocking with spies (Advanced) explains the steps to mock only a few methods of a given class while invoking the real implementation for all other methods. This is achieved in PowerMock by creating spies.
Mocking private methods (Medium) covers the steps to mock and verify private methods. Private methods are difficult to test with traditional mocking frameworks. But for PowerMock, it’s a piece of cake.
Breaking the encapsulation (Advanced) shows how we can test the behavior of a private method and verifies the internal state of a class using the Whitebox class. At times, some private method might be performing an important business operation and we need to write unit tests for that method. The Whitebox class can be very handy in such situations.
Suppressing unwanted behavior (Advanced) explains how we can suppress unwanted behavior such as static initializers, constructors, methods, and fields.
Understanding Mock Policies (Advanced) demonstrates the use of Mock Policies to better manage the repeated code needed to set up mocks for a complex object.
Listening with listeners (Medium) demonstrates the steps to listen for events from the test framework. We might want to do some processing when the test method is invoked or create a report about how many tests were run, how many passed, how many failed, and so on. Listeners are a good fit for such requirements.

Sunday, August 29, 2010

How to mock/stub void static methods using PowerMock

In my previous post we saw how we could mock/stub void instance methods.
In this post we will try our hands at mocking/stubbing another exotic species called void static methods

Yes, I know void static methods should be avoided at all costs!

But sometimes you just cant help it!

So lets look at the code under test

In our example we want to test the upgradeAllCustomers method of the CustomerController.

This method upgrades all customers by invoking a void static method upgradeAll on Customer class. Currently implementation of upgradeAll method of Customer class throws and exception.  

What do we want to test:
  • upgradeAll void static method of Customer class was invoked
  • true is returned after the upgrade
How will we test it - How do they do it!:

The syntax that we had seen in the earlier post will now work anymore

If we notice persist is an instance method on the Customer class (and the above syntax works for instance methods only).

But in this case we want to stub the void static method. How do we do it?

We have to do the following things

  • Use the annotation @RunWith(PowerMockRunner.class) to bootstrap PowerMock itself
  • Use the annotation @PrepareForTest(Customer.class) to be able to stub static methods of Customer class.
  • Stub the void static method using the following lines of code

Notice that the syntax is a bit like record-playback-verify style.

We have to first tell PowerMock to do nothing when a static method is invoked on Customer class.

PowerMock should do nothing on which void static method is specified in the next line by invoking the void static upgradeAll method on the Customer class.

Its effectively recording the fact that, when static void upgradeAll method is invoked on Customer class nothing is to be done!

Before moving, lets see how can we verify that a void static method was actually invoked?

We can easily see that the syntax to verify that a static method was invoked also follows the record-playback-verify pattern.

First we have to inform PowerMock that we are going to verify a static method invocation, and in the next line we actually verify the call to the upgradeAll method.

Enough explanation lets look at the complete test code:

Yes thats how we do it!

For the first time I have to say, and believe me I hate to do so but, I don't like this syntax that much!

But that's just me and hats of to the excellent job that PowerMock and Mockito guys have done so far!

How to mock/stub void methods using PowerMock

Ok, I had though that the previous post would be the last post in the how-to series, but there are so many features in PowerMock that I am tempted to write more about it :)

So, here comes another post on how to mock/stub void methods using PowerMock.

One would think why are void methods so special, that we need a post to explain them?

Well thats because they are void methods. They don't return anything. If you remember, from my earlier post, the syntax of stubbing any method with a non void return type is as follows

In the above example doSomething method of ServiceA instance returns a String.

But imagine what will be the syntax, if doSomething method's return type was void!

May be something like this?

But, if you think for a moment about the above syntax, we would realize that  

methods in java are not very happy to accept void as the argument type!

Effectively, in the above syntax the when method is taking void as one of the argument!

Well this is a problem. This cannot happen!  Hence, we need a special syntax to mock/stub void methods.

So without wasting any more time lets look at the code under test:

In our example we want to test the persistCustomer method of the CustomerController. This method simply calls persist method on the Customer instance passed as argument. Assuming that the persist method of the Customer class returns nothing if everything is fine and throws a RuntimeException if something horribly goes wrong.

We want to write the test case for both these scenarios. So how do we do it?

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

Well, there is always a way with PowerMock!

Our first scenario is to verify that the persistCustomer method returns true if everything goes fine.

PowerMock uses the following syntax to stub the void method to do nothing.


If we read the syntax in pure English it says,

Do nothing when persist method is invoked on customer instance

As simple as that! We are telling the mock customer object to do nothing when persist method is invoked.

Lets look at the test case:


Now the other scenario, we want to make sure that false is returned when an exception is thrown from the persist method of customer instance, but for that to happen we have to stub the persist method of customer to throw an exception.

This is how we do it:

Syntax in English:

Throw RuntimeException when persist method of customer instance is invoked.

Lets look at the test case:

Thats it! Well you see there always is an easy solution with PowerMock

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!

Saturday, July 17, 2010

How to use argument matchers using PowerMock

In my previous post we saw how we could suppress a field. In this post, we will write test case for a more common scenario.

Every time when we stubbed out a method or verified an invocation we have used actual arguments, for e.g.

Or

Notice the argument that we are passing to method2 is "some argument value".
By default PowerMock invokes the equals method on each argument to find whether the arguments match or not.

But what if we want to write the test for the below code

Code Under Test:

Well, looks pretty straight forward class to test. But wait, have a look at the arguments been passed to anotherBusinessProcess method.

The first argument is "Hello World" thats not the problem, the real challenge is the second argument "Another argument + Math.random()". Any one who has worked in Java for a day knows that Math.random() with generate a random number :) and since its "random" we cant determine what is the number till its generated!

So how do we stub the anotherBusinessProcess method on the ServiceB class.

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

Well in such cases where we don't know exactly what argument will be passed to a certain method (which we want to stub) we could use a feature of Mockito called Argument Matchers.

Mockito has a rich set of predefined argument matchers. As the name suggests, argument matchers job is to match the arguments! As in this case we don't know what is the exact argument passed to the anotherBusinessProcess, hence we might say that

"Stub the anotherBusinessProcess method on ServiceB when its invoked with argument Hello World and any string to return Success!"

If you read the statement above carefully, we want to make sure that, the first argument of anotherBusinessProcess method is "Hello World" but the second argument could be "any string". How do we do that? Using Mockito's argument matchers.

The syntax:

Notice that we are using two argument matchers in the above example
  • eq: used to say that the argument passed while invoking the method from the test code is equal to the argumnet passed to the eq method
  • anyString: Means, the argument is any valid string!
NOTE: The difference between the two lines in the above example. In the commented line we are not using the eq argument matcher. The rule is if you are using Mockito argument matcher for one argument you have to, have to, use it for all the other arguments as well.

Hence if you ran the test case using argument matcher for only one argument and passed actual value for the other then Mockito will throw following error

The error message is self explanatory and it give a right solution to the mistake! This is the Mockito's goodness, its extremely intuitive and gives us an awesome error messages!

Moving on, now that we know how to correctly stub anotherBusinessProcess method lets look at the whole test code

anyString does the job for us. But the problem is, it will match any string (well, that is exactly its job! which it does well BTW), what if we want to say that the second argument should startWith "Another argument "?

Mockito has a solution for this as well! Use the startsWith argument matcher.

here is the complete test code.

Mockito has lot of built in argument matchers that we could use, I strongly suggest looking at this link for more examples.

Other argument matchers that could be of interest.

  • isNull - Matches an argument that is null
  • isNotNull - Matches an argument that is not null
  • isA - Matches an argument that is A instance of the given Class
  • endsWith - String that ends with the given value
  • anyCollection - Matches any collection
  • anyMap - Matches any map
  • matches - Matches a regular expression
  • any - Matches any object.

How to fix the OutOfMemoryError when writing tests with PowerMock - Part - 2

In my previous post we had a look at How to fix the OutOfMemoryError when writing tests with PowerMock

Looks like, the method I described in that post does not work on all machine or environments.

In one of the environment whose configuration is:
  • Windows 7 64 Bit
  • 4 GB RAM DDR3
  • Intel Core i7 processor
  • JDK 6 64 Bit  
  • PowerMock 1.3.7  
it seemed to work for some time, but as soon as we wrote a few more tests using PowerMock (Mockito api), the OutOfMemoryError re-appeared.

Now that's annoying, what the hell is wrong now!  Well as I said in the previous post memory leaks are hard to find and fix!

But we need a solution now!  Can't wait till PowerMock 1.4 version is released.  Hence, I was on a mission to fix the issue and get all my tests running by hook or crook!

In the process I found that, running the tests on a 32 bit machine had no problems what so ever!  Surprise, Surprise!

Investigated a little further, found that when tests are run on a machine with 64 bit OS but 32 bit JDK they all pass.  That was the moment of Truth!

These are the steps I followed to fix the OutOfMemoryError:
  • Installed the JDK 6 32 bit on my machine
  • Updated the JAVA_HOME environment variable
  • Added the JDK 6 32 bit bin directory to the PATH environment variable
  • Removed the earlier JDK 6 64 bit bin directory from the PATH environment variable.  
All set!  Ran all the test and bingo!  All pass its a SUCCESS!

Saturday, July 3, 2010

How to fix the OutOfMemoryError when writing tests with PowerMock

We use PowerMock (With the Mockito Api) in our current project as the Mocking/Stubbing framework. It has worked our really well so far!

Completely in love with the Mockito syntax and especially the error messages that it gives out when something is wrong.
Love the power that PowerMock adds to Mockito which enables us to test the un-testable code. The combination i.e. PowerMocks with Mockito, makes it a deadly combination to ignore and I call it Mocks on Steroids!

But life is not always perfect! is it? Recently I faced a situation, suddenly out of no where I started getting the

infamous java.lang.OutOfMemoryError: PermGen space  Error here is the stack trace.

Man! its always a challenge to fix such issues.
Googled a little, found that its a known issue have a look at this url

Its caused because of a Memory leak (wow! as if I am telling something new! Its obvious, we get OutOfMemoryError when we have memory leaks! Everyone knows that!). Yes, and as you guys already know finding the source of memory leak is a challenge in itself.

But looks like, they have narrowed the problem down to the MockClassLoader class.

The problem:

If your project uses third party frameworks like log4j or spring, then those classes are also loaded by the MockClassLoader class. Causing log4j or spring classes to be loaded multiple times by multiple instances of MockClassLoader class.

The long term solution:

This problem will be fixed in the PowerMock's 1.4 version for sure!

But what should you do if you can't wait till then?

The short term solution:

Use the @PowerMockIgnore annotation. This annotation signal PowerMock not to load third party framework jars such as log4j and spring using the MockClassLoader. Let the system class loader load them.

The sample test case looks like this

That fixes the problem for our project!

This problem is a perfect example of the fact that, there is always a flip side!
But, if the flip side is not as bad, then as said by Amir Khan in the movie 3 idiots

All izz well!

Monday, June 28, 2010

How to suppress fields with PowerMock

Now why would you want to do that! Lets look at the code straightaway.

Code under test:

The AccountDAO class has a "session" field, which has been initialized where its declared. Assuming that Session class in our example, is a wrapper over the the Hibernate Session class which talks to the database and does stuff for us.

BTW I couldn't agree more that its a terrible design!

So, basically what we want is to suppress the field "session" and instead use a stubbed Session instance.   Which means, we would stub out the getSession method, to write good unit-test case for the findAccount method.

So how do we suppress the field "session"

How would we test it - How do they do it!

The suppress method (which we had a look in the earlier post) can not only suppress the methods but can also suppress fields.


The Syntax:

What does the above syntax mean? Just read the line in plain English and that is exactly what it means!

Suppress the field of AccountDAO class called "session"

After this statement if we call getSession on any instance of AccountDAO it will always return null.

Q: But how can PowerMock do it?
A: Via byte code manipulation.  Remember our old friend @PrepareForTest(AccountDAO.class) annotation.

So we have solved one part of the problem. The next problem is to return a stubbed session instance when getSession method of AccountDAO is called. How can we do that?
A: Remember partial mocks via the spy method

That makes the problem look much simpler right?

So lets look at the test code:

Yes! We have managed to suppress a field for any given class.

Really, PowerMock's (using the Mockito api) keeps dazzling us with its Power!

Monday, June 21, 2010

How to suppress static initializers using PowerMock

In my previous post we saw how we could test methods of class whose constructor does evil stuff.  What if the static initializer of the class does evil stuff?  How will we test such a class?
This is exactly what we are going to see in this post!

You might think why on earth would you want to do that? For a few very simple reasons like, legacy code, third party library, may be something else.

At times, we might have to use a third party library that does some weired stuff in static initializers. It might load a native library, may perform some IO operation, may open up a database connection etc.
When we are unit-testing a class that uses this third party class (whose static initializer does wired stuff), we simply don't want to deal with all this complication.

This is the reason why we might want to suppress the static initializer of a class.

Convinced about the "why"? Lets look at the "What" part.

Code under test:

Hmmm, looks like a familiar class?
We want to write a unit-test case for the AccountDAO class. In that we are interested in testing the findAccountById method. This method get a Hibernate session from HibernateUtils class and then invokes the get method on the session.

But look at how HibernateUtil class.  It initializes the static SessionFactory instance.  It does that in a static initializer!  Man! this means every time the unit-test case for AccountDAO is executed the sessionFactory will be created. We don't want that to happen do we?

Also notice that, for testing purpose I have a System.out.println line in the static initializer of HibernateUtil. If we are successfully able to suppress the static initializer of HibernateUtil we should not be getting any output on the console.

So how do we write unit-test for AccountDAO class without initializing the SessionFactory.  Lets look at the "How" part now.

How would we test it - How do they do it!

Turns out, as always, there is a very simple way to suppress the static initializers of any class using PowerMocks - Mocks on Steroids! 
We simply have to use an annotation called @SuppressStaticInitializationFor.  As the annotation reads it suppresses static initializer for a given class.  But which classes static initializer do we want to suppress?  How do we tell this to PowerMocks? Via passing the fully qualified class name to the @SuppressStaticInitializationFor annotation.

Here is the syntax

Please note that we are passing the fully qualified class name as string to the @SuppressStaticInitializationFor annotation.  Unlike in the case of @PrepareForTest annotation where, we pass the class reference like this

Can you tell me why this difference in the syntax? Well, for those who have not guess it, here's the answer:
Because if we pass the class reference like HibernateUtil.class then, by the time that statement executes the class is already loaded and static initializer would have already been executed. We don't want that.
Sole purpose of using the @SuppressStaticInitializationFor annotation was to suppress the static initializer of HibernateUtil class. And this is the reason we don't pass the class reference but we pass the fully qualified class name as string.
After a lot of explanation lets look at the complete test code

Thats it! We have managed to suppress the static initializer of a class.
Writing unit-tests with PowerMocks (Mockito api) is fun!
BTW the statement "The static initializer of HibernateUtil invoked" is never printed on the console. You will have to take my word for this! What? You don't trust me? Then, try the example on your own :)

Wednesday, June 16, 2010

How to test methods of a class whos constructor is evil, using PowerMock

As promised in my previous post, today I will show, the second way to write test cases for methods of a class whose constructor does crazy stuff.
Example of "crazy stuff" would include opening a db connection, load a native library etc. There are many things that would come under the "crazy" umbrella but lets not go there.

Code under test:

You remember our dear friend Mr. LegacyCustomer right? Yes this class has an evil constructor that does some crazy stuff, in our case it throws a RuntimeException. Effectively, this means we can never create an instance of this class, as there is not constructor that we could invoke.

One of the way to test the method getCreditLimit would be to suppress the constructor of LegacyCustomer using the suppress method which we have already seen in the previous post. So what is the other method to test it?

(On the side note, most Mocking framework don't even have one way to write test for the above code but PowerMock's has two ways in which we could test the above code! How awesome!)

How would we test it - How do they do it!

Turns out, there is a class called Whitebox in PowerMocks using which we could instantiate a class without invoking its constructor. Whitebox class has a lot of features to bypass encapsulation of a class but we will discuss those features later. Today lets focus only on instantiating the class and testing the getCreditLimit method.

To instantiate the class using Whitebox class we use the following syntax

The newInstance method on the Whitebox class takes the name of the class that has to be instantiated without calling the constructor.

Now writing the complete test case would be tad simple. Lets look at the complete test code

Note that we don't even need to use the @RunWith and @PrepareForTest annotations. Whitebox class can instantiate LegacyCustomer without even invoking the constructor.

Please note: If we had to write the test case using the suppress method we would have to use the @RunWith and @PrepareForTest annotations.

Life looks a lot better when we have powerful tools like PowerMock (with Mockito api) at hand!

Monday, June 7, 2010

How to supress methods and constructors using PowerMock

We have come a long way in our how-to series, demonstrating the power of PowerMocks (with the Mockito api).  I hope you are liking it as much as I like writing about it!

In the earlier post we saw how we could partly mock classes and its private methods using PowerMocks.  Today I will demonstrate how we could suppress a constructor and a method.

Now you must be thinking why the hell would I every want to do that!  Well believe me there are cases where you would want to do that :)  And we are about to have a look at one

Code under test:

Now you understand why we might need to suppress a constructor?  Well as we can see in the above code class LegacyCustomer's constructor simply throws RuntimeException (this is just a place holder.  In real world it might do some complicated operation may be loads a native library, establishes a connection to the db god knows what all it can do!).  Customer class extends LegacyCustomer class to add some more behavior to it (I am so making it up!).  In real life, I would never write such code.  Believe me!

But lets assume for now that we want to write a test case to verify that, when the Customer object is created it sets the email field to the value passed as argument.

So how do we test this?

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

We can easily suppress the constructor of LegacyCustomer class.
"Suppress a constructor" means that the code in the constructor will not be called and thats exactly what we want.  The syntax to do that is

Lets read the above line in English.
Suppress the constructor of LegacyCustomer class which takes one argument of String type.  Nice job!
This is step 1 of the process.

Now, if you think for a moment, base class constructor will be invoked automatically when derived class instance is created right!  Hence, in this case LegacyCustomer class's constructor will be invoked as soon as we create an instance of Customer class.

We dont want that to happen!
We want to suppress the call to the constructor of LegacyCustomer class.  So we will have to change the byte code of Customer class and tell it not to invoke the Constructor of LegacyCustomer class.

How do we do that?  Well, you know the answer to that using the following line of code

PowerMocks is happy to do the all byte code manipulation for us, we just need to tell it to do so.  This is done via our very own @PrepareForTest annotation.

So lets look at the entire test case

Simple?

Want more?

What if, I wanted to test a method in Customer class that actually invokes another method that does some complicated stuff?

Lets look at the code to test:

Well its basically the same code as above we have just added the getNetAssetValue method to the Customer class and we want to test this method.

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

One way to do that is of-course by using spy and then stubbing the private method.

The other way is to suppress the call to doSomeComplexCalculation method.  What is the syntax for doing that?

Again, lets try to read the above syntax in English language.
Suppress the method of Customer class whose name is doSomeComplexCalculation
 Nice!

Lets look at the complete test case


That's all folks!

Looks like now we know how to suppress any constructor or a method!  Well, what if we wanted to test some method in LegacyCustomer class?  Remember the LegacyCustomer class constructor throws a RuntimeException.

Hummmm, that's interesting how can we suppress the constructor of class under test.  Turns out there are two ways of doing it.  One of the way is what we have just seen, using the suppress method.  Will show the other way in the next post.

Till then, Have Fun with PowerMocks!

Tuesday, May 25, 2010

How to partially mock a class and its private methods using PowerMock

Earlier, in the how-to series we had seen how-to mock constructors.  In this post we will have a look at how-to partially mock classes and even their private methods using PowerMocks - Mocks on Steroids!

Lets first look at the code to test before I start with my rambling

Code under test:

We want to write a test case to test method1 of ServiceA class.  ServiceA's method1 invokes method2.  method2 performs some complicated business logic - in this case creates an instance of ServiceB and invoked doBusinessOperation on that instance.

There are two approaches to test ServiceA's method1.


  • Write the test case to mock out the ServiceB's constructor and assert that doBusinessOperation method was invoked on the mocked ServiceB object.
  • Stub the method2 call!  Only verify that from method1 a call was made to the method2.

We already know how to write tests for the first approach.  Today we are more interested in looking at how do we write tests for the second approach.

Why would we ever choose the second approach over the first approach?  May be because method2 was already tested in some other test case.  Hence, we just want to make sure that method1 calls method2 with the right arguments.

So how do we partially mock ServiceA?

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

PowerMockito class provides a method called spy to create partial mock of a class.  This method takes an instance of the class that you want to partially mock as argument (in this case ServiceA).  Why? Because we want to invoke actual implementation of method1 and mock only method2.

Syntax

Then, we want to stubb out the method2 and return some dummy value.  This how its done

Notice the difference in the syntax then the regular when-theReturn syntax.  As, if we use the when-thenReturn syntax actual call to method2 will be made!  Why? Because PowerMocks does not know whether you are setting up an expectation on a partial mock or actually invoking the method.  Hence, be careful with partial mocks and choose the right syntax.

How to verify that the method was actually called?

No surprises here.

The full test case would look like:

A variation of the above example, what if the method2 was private?  Can we still stub it?  Of-course the right answer is YES!

Code under test:

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

Now, the above doReturn-when-method2 syntax wont work.  As method2 is private and is not accessible outside the scope of the class.  How do we stub it then?

Only change is, we pass in the name of the private method to stub as string argument to when method.  when method also accepts the var args array of arguments to the method2.

To verify that the private method2 was invoked use

Here also, instead of verify we use verifyPrivate and call a invoke method which accepts, name of the private method and its arguments.

Full test case would look like this:

Yes!  Thats it.  We have achieved what we intended to do!  PowerMock's is really a valuable tool to have in once arsenal!

How to mock constructors using PowerMock

In the how-to series today I will show how-to mock constructors using PowerMocks - Mocks on Steroids!.  In my previous post we saw how can we write unit-tests for mocking final methods and classes.

Requirement:

Again, taking a fictitious example, lets say that ServiceA creates an instance of ServiceB and invokes a businessOperation on ServiceB's instance.  ServiceB's constructor is evil and it throws a Exception.  We want to test this code.  Lets look at the code under test

As we can see, ServiceA's doSomething method create an instance of ServiceB class (by invoking a constructor with no arguments) and then invokes doBusinessOperation() method.  Looks like a simple class, but wait, have a look at ServiceB's constructor, its evil, it throws an exception!  Now how do we mock the constructor so that we can write a good tests case for ServiceA's doSomething method?  Simple, Using PowerMocks (Mockito api) :)

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

We have to use @PrepareForTest annotation with ServiceA class as, it instanciates ServiceB and we actually want to inject a stub on ServiceB so that we can verify that doBusinessOperation method was actually invoked.

Then, we use the whenNew method of PowerMockito to actually return a stub of ServiceB when a new instance of ServiceB is created using a no argument constructor.

Just read the above line in and then compare the syntax below

We can actually read the code in English and it does make a lot of sense!

Lets look at the test code now:

Piece of cake isn't!

Tuesday, May 11, 2010

Testing the Untestable code using PowerMock (Mockito api)

Taking inspiration from this excellent post by Johan Haleby, today I am going to jump a few gears and show you the real power of PowerMocks.  I will show you how can we write good unit-tests to test the untestable code!

We will continue the How-To series using PowerMocks (Mockito api) but today lets look at something more complicated.

You must be thinking, if the code is untestable then how can we write unit-tests?  But, that my friend is the real power of PowerMocks, we can write unit-tests for testing untestable code as well!

So What are we testing today.

Code to Test:

The code example is taken from one of the code samples of JMockit unit-testing framework (which by the way is another powerful unit-testing framework).  At first glance the code might not look as complicated, but make a note of the following points and then think how will you ever write a unit-test for doBusinessOperationXyz method?

  • The ServiceA class is final
  • It invokes a static method on Database class called find which returns a list
  • It then creates a new instance of ServiceB class and invokes computeTotal method, passing it items retrieved from Database.find call
  • ServiceB class is final as well
  • Invokes another static method on Database class called save, passing it the EntityX instance

Wow! it seems like a really tough class to test.  Lets move ahead and write some good unit-tests to test the above code!

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

You will be surprised to know that, we could write multiple unit-tests for the above code depending on what exactly we want to test!  How awesome!

Test Requirement 1:

Lets say we want to test that, the ServiceB was invoked to compute total.

Test Code:

As usual we have to annotate the TestCase with @RunWith annotation (go here know more on why we have to do so).

We can verify that computeTotal method was invoked on ServiceB instance via a mocked ServiceB object. But if you think about this for a moment, how can we do that?  Because ServiceA's doBusinessOperationXyz is actually instantiating ServiceB.

How can we suppress this behavior and inject our mocked ServiceB object?  Simple! via byte-code manipulation of ServiceA class :)

No no, don't worry, we don't have to do byte-code manipulation on our own, PowerMocks does that for us.  All we need to tell PowerMocks is for which classes we want to perform byte-code manipulation using the @PrepareForTest annotation (go here to know more about @PrepareForTest annotation).

Another point is we want to mock static methods in Database class as well.  Hence we have to use @PrepareForTest annotation for Database class as well.

And finally, note that since we want to mock ServiceB class, which is a final class we have to use @PrepareForTest annotation for ServiceB class as well.

Enough fluff, show me the stuff!

The unit-test code looks like this

Thats all folks!  We have successfully tested the Untestable code for our first requirement


Thats all folks!  We have successfully tested the Untestable code for our first requirement

Test Requirement 2:

Lets say we want to test that, the Database was used to save EntityX.

Test Code:

Now that you have read the post so far, this one must look straightforward to you!

The test-case looks like

Thats it!

Test Requirement 3:

Database find was invoked to get the list of EntityY

Test Code:

The test-case looks a lot similar to the previous example

I promise its not much after this.

Test Requirement 4:

Should verify that EntityY list returned from Database.find was used to computeTotal

Test Code:

This is the final one.

Test Requirement 5:

Should verify that computed total was set on EntityX instance

Test code:

Done!  Its pretty evident from the above examples that testing the Untestable code is pretty easy using PowerMocks (Mockito api)

Feedback, questions and comments are welcome as usual!
Have some Fun!