XNSIO
  About   Slides   Home  

 
Managed Chaos
Naresh Jain's Random Thoughts on Software Development and Adventure Sports
     
`
 
RSS Feed
Recent Thoughts
Tags
Recent Comments

Constants and JUnit

On my current project we have a requirement that we need to log every method entry and exit. For purpose of this post let‘s consider a simpler example.

public class Calculator{
private final LoggerWrapper logger;
static final String ADD_METHOD_SIGNATURE = “add(int, int)“;

Calculator(LoggerWrapper logger){
this.logger = logger;
}

public int add(int firstOperand, int secondOperand) {
logger.logMethodEntry(ADD_METHOD_SIGNATURE);
int result = firstOperand + secondOperand;
logger.logMethodExit(ADD_METHOD_SIGNATURE);
return result;
}

}

Since logging method entry and exit is a requirement we need to write unit tests to make sure we are logging the correct messages in the right sequence.

We started using easymocks and constructor based dependency injections.

Since our unit tests reside in the same package as the classes, [in a different source tree of course], we use package protected constructors to inject the logger.

//test class
import org.easymock.MockControl;
import junit.framework.TestCase;

public class CalculatorTest extends TestCase {

public void testAdding3To5Returns8() throws Exception {
MockControl loggerControl = MockControl. createStrictControl (LoggerWrapper.class);
LoggerWrapper mockLogger = (LoggerWrapper) loggerControl.getMock();
Calculator calculator = new Calculator(mockLogger);

mockLogger.logMethodEntry(Calculator. ADD_METHOD_SIGNATURE);
mockLogger.logMethodExit(Calculator. ADD_METHOD_SIGNATURE);

loggerControl.replay();
assertEquals(8, calculator.add(3,5));
loggerControl.verify();
}

}

This works perfectly fine. This test makes sure that logMethodEntry and logMethodExit is called in the same order and with the correct parameters. [method signature in this case].

So if you notice, we have defined a constant called ADD_METHOD_SIGNATURE in the Calculator class. We are using this constant in the test and making sure the logger methods are called with the correct method signature.

Using constants in this fashion surely has advantages. For Ex. someday we change the add method signature, we just need to update this constant and the tests will still pass. But the same advantage can turn into a big disadvantage if the constant value goes out of sink with the actual method signature. So, if we change the method signature and don‘t update the constant, the test would still pass, which is wrong. The tests should be checking for the absolute value in case of logging.

We have 2 approaches to tackle this.
1. Don‘t use the constant in the test and use the actual value. So if you change the method signature and don‘t update the constant, you‘ll have a failing test.
2. The second and the better approach is to use the constant in the test, but also add another test which checks for the absolute value of the constant.

public void testConstantValue() throws Exception {
assertEquals(“add(int, int)”, Calculator.ADD_METHOD_SIGNATURE);
}

Now you know, what‘s keeping me busy whole day 😉


    Licensed under
Creative Commons License