Wednesday, July 30, 2008

Have you tested your code ?

As I work daily, I am beginning to understand the difference between a programmer and a Development Engineer. How many times would you have written a test module for the API that you just coded ? AFAIK, it only used to be a manual testing to check whether everything is working fine. Let me take you to a new domain...lets call it the 'TestDomain' :-)

In a typical S/W company, you tend to write code that satisfies some business logic. It's no longer finding out the shortest path or the MST :-). The code might involve retrieving values from databases, usage of web services, etc. Hence, each module needs to be tested. To our rescue, comes a nice neat package "JMock" !Astounded by its power, I just love writing test cases now :-).

So, what is this JMock all about ?
JMock is a library that allows you test Java code with the help of mock objects.

Mock object ? Enlighten me pl.
Hmmm.... Say you need to test a module, Module 1

Module 1

class Module1{
Webservice service;

String ipAddr;
public setService(Webservice serv){
service = serv;
}

public String getIpAddr(){
return ipAddr;
}

public void function(){
ipAddr = service.getIPAddr();


if( ipAddr == blah...blah... ){

set ipAddr value = "val";

}
else {
throw Exception
}
}
}
There are 2 ways to test this module.
  • Initializing the service and checking whether the ipAddr value has been set or an exception is thrown
  • Mocking the service
We are here to discuss the 2nd point. Instead of initializing the service and making the call heavy, instead you can mock the service object, (i.e) JMock allows you to create a "mock" WebService object which to the Java code will look like a WebService object.

Still hazy :(
Basically, instead of hitting the service, you try to define how the service object will work given a set of parameters. To put it crudely, it essentially means, you are trying to override the WebService functions when passed with a specific set of parameters.

Nice :-), Eg?
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;

@RunWith(JMock.class)
class PublisherTest {
Mockery context = new JUnit4Mockery();

/* I am mocking the webservice object here */

final WebService webservice = context.mock(WebService.class )

/* Don't panic! Its simple :-) All I am asking it to do is, when the webservice object
calls the getIpAddr() function, DO NOT call the service, instead return the value I have specified */

context.checking(new Expectations() {{
one (webservice).getIpAddr();
will(returnValue("127.0.0.1");
}});

Module1 moduleObject = new Module1();

/* Set the service used to be the mock object :-) */
moduleObject.setService(webservice);

/* When I invoke this, the original service isn't called, the mock object takes over*/
moduleObject.function();

/* Assert statments follow here */
Assert.assertNotNull(moduleObject.getIpAddr());

}

src: jmock.org

Well JMock is a huuuuuuge library with so many functions and you can keep playing around with it. With this knowledge, you can go through the cheatsheet and get greater power. And ofcourse, I am always right here to help you out with anything related to JMock :-), anything :-)

Btw, I forgot to tell you something, NatPryce replies to mail like a lightning! Till date, he has sent me about 10 mails!!

Who is NatPryce ?
Go figure it out :P

PS: Could someone pl. tell me how to indent code snippets! The blogspot "Edit Post" tab is a piece of shit!!

1 comment:

Anonymous said...

I think you can give links to code if they exceed 10 lines.