EmailLinkedInGoogle+TwitterFacebook

I am a heavy user of test driven development and the practice has paid off very well over the last few years in two important fronts.

  1. A great reduction in bugs
  2. Absolute confidence while undertaking changes to existing code base

A recent discussion at a team meeting prompted me to start thinking in an interesting angle.

Why not use Junit assertions all through the software to write fail fast code?

Fail fast code is one that just refuses to bury errors. For example look at the absolutely ridiculous (if not funny :-) ) code snippets below.

public void failFast(){
	Random random = new Random(System.currentTimeMillis());
	boolean failFlag = random.nextBoolean();
	if (failFlag != true) throw new RuntimeException("Unexpected value for failFlag : " + failFlag);
	//Continue Doing stuff....
	//...
	//...
}

public void failNotSoFast(){
	Random random = new Random(System.currentTimeMillis());
	boolean failFlag = random.nextBoolean();
	if (failFlag != true) failFlag = true;
	//Continue Doing stuff....
	//...
	//...
}

The first one is ‘fail-fast’ and the second is ‘very accomodative’.

You will be able to relate to many other instances from your experience where you use ‘defaults’ to cover possible points of failures buried deep inside the code. Problem with burying possible problems is that debugging becomes increasingly painful. Support team will break their head on why the hell is the system just not understanding ‘What the user wants it to do?’

This brings us to the discussion as to how I see Junit as a possible tool to resolve this problem. Traditionally we are familiar with writing robust test cases. However I have not used Junit classes in my application. What if, we just start using the Junit4 class org.junit.Assert to make sure that everything is working fine? Let me try to see whether this is practical.

Source code of ‘FooValidator.java’ is available @
svn checkout https://whiteboardjunkie.googlecode.com/svn/trunk/jackrabbittutorial jackrabbittutorial

public void foo(Map<String,String> fooParameters){
	//Asserting that the incoming parameter is not null.
	//If null (or invalid) fail with appropriate message
	//by throwing an AssertionError
	assertNotNull("fooParameters cannot be null", fooParameters);
	Set<String> keys = fooParameters.keySet();
	
	for (String aKey : keys){
		String value = fooParameters.get(aKey);
		//Asserting that each parameter carried in the map is good
		//good for use.
		assertTrue(	"Parameter " + aKey + " = " + value , 
					((value != null) &amp;&amp; !value.trim().equals("") 
					) );
	}
	logger.debug("All parameters are good , Proceeding to execute");
	//DO Stuff...
}

To me it looks like a great convenience to use the ‘Assert’ from Junit for doing simple validations. All you would have done anyways is to throw an exception with logging and that is exactly what you get to do when using the static methods from Assert. For example if I invoke the above method through main by supplying the following Map as parameter,

mvn clean compile exec:java -Dexec.mainClass=org.boni.jrtutorial.util.FooValidator -e

Map<String, String> parameterMap = new HashMap<String, String>();
parameterMap.put("First Param", "Good");
parameterMap.put("Second Param", "Very Good");
parameterMap.put("Third Param", "    ");

The program fails with an exception :

...
Caused by: junit.framework.AssertionFailedError: Parameter Third Param =
        at junit.framework.Assert.fail(Assert.java:47)
        at junit.framework.Assert.assertTrue(Assert.java:20)
        at org.boni.jrtutorial.util.FooValidator.foo(FooValidator.java:35)
        at org.boni.jrtutorial.util.FooValidator.main(FooValidator.java:49)
...

This behavior is very accurate and is as expected.

The advantages are that

  • the code is very clean and easy to read
  • Can assert a wide variety of conditions very easily
  • AssertionFailed error with an appropriate message conveys the meaning of the error condition very accurately

One disadvantage I can see is that AssertionError is extending java.lang.Error, which traditionally is used to convey fatal error conditions.

This discussion will not be complete without addressing a very serious contender, the one built into the java language itself, the ‘assert’ key word. JDK 1.4 introduced ‘assert’. There are options to compile the code with assertions or not. A detailed feature discussion can be found here. It can assert if a boolean expression is true. I do not find it as powerful as the static assertions that come with Junit.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation