Showing posts with label partial mock. Show all posts
Showing posts with label partial mock. Show all posts

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!

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!

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!
Have some Fun!