Showing posts with label private. Show all posts
Showing posts with label private. Show all posts

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!

Tuesday, September 30, 2008

Ruby Private Methods

I have started learning ruby very recently and came across a very interesting visibility issue. We can never invoke private methods with an explicit receiver. For e.g.


In the above example the call to any_method would fail because we are trying to invoke any_private_method using a receiver. We cannot do that even if the receiver is self.

However following code would work.

In the above example we are invoking the private method without any receiver from within the object and hence it works.
Have some Fun!