Friday, January 11, 2008

Policies and AntiPatterns in Junit

Now that you took the first step towards the automation testing, its time to know the rules and play by them… Today, I’ll try to list down the policies that we should follow and what are the antipatterns available in Junit.

Policies:

1) Write Unit tests only for the code which is visible to other classes. You can just write tests for only the complex methods in a class, but there’s no rule of thumb for determining whether the given method is a complex method to test or not. But we can get a viable answer from the C.R.A.P formula used in Crap4J plug-in.

2) The purpose of the unit test is only to test a particular piece of code, it doesn’t make sense to implement anything more than that in a junit test case so, it should not involve complex logic like connecting to Database or setting up property files etc. You can make use of Mock objects to avoid the situations mentioned above.

3) Your unit testing code should clean you actual functionality with effective refactoring techniques, but in any case you actual code should not be changed just to make work with your Unit testing code. We should always try to make it more testable in nature, but not directly rely up on the unit testing code.

For example : You can not have logic something like this in the core part of our code..

If (isTestingMode)

//do following…

Else

// do following…

4) Mock object should be only used as a substitute of an existing object, it SHOULD NOT contain any application specific code inside it. ( Is this what we’re trying to simulate using this object ? )

For example : Lets say we've an object in the actual code that we use to fetch various property values from a property file. The method you wanted to test is written something like this...

public void methodToTest()
{
// Some application specific code
PropertyManager mgr = PropertyManager.getInstance();
String propertyName = "SomePropertyName";
String propValue = mgr.getPropertyWithName(propertyName);
// manipulating the property value here.
}

For unit testing this method, you don't need to have MyBundle.properties in the classpath, you can pull out the code which reads the property from the property file and instead pass it as an argument like this.

public void methodToTest(PropertyManager propMgr)
{
// Some application specific code
String propertyName = "SomePropertyName";
String propValue =
propMgr.getPropertyWithName(propertyName);
// manipulating the property value here.
}

Now, our code is ready for unit testing and we can mock the Propertymanager by asking it to emulate the call to 'getPropertyWithName(...)' method by returning our required values ( or behavior ). So, our mock object should look like this.

MockPropertyManager extends PropertyManager
{
public String getPropertyWithName(propertyName)
{
if(propertyName == "SomePropertyName") return "correspondingValue";
}
}

At this point, we've removed the dependency of a property file from our code. Now,we can test this code without worrying about setting up the whole environment around it.

I'll elaborate more about using mock objects in my coming articles...

Anti patterns :

Anti patterns are things we shouldn’t do or against the standard while writing any piece of code/work. We’ve antipatterns for Junit as well, and internet is filled with numerous number of articles discussing about these. As you can see, this topic is pretty dynamic in nature and new patterns are kept on adding every day.. ( well, don’t know where exactly they add, but they mention all these new items in blogs and there’re ppl who’d like to archive all these things and keep them at one single place)…

When I started looking for these things, I stumbled across one interesting article which talks especially about “Junit antipatterns”. You can just go through it and you’ll know what I’m talking about.


No comments: