Thursday, November 09, 2006

JUnit Best Practices, Part 3 -- Constant Expectations

You've just written your new doComplicatedCalculation() method and you're ready to test it, so you create the following unit test:


It seems straightforward enough. You invoke the method under test and compare it to an expected result to see if it matches. The problem is that the use of the computeExpectedTestResult() method is double trouble.

First, it appears that computeExpectedTestResult() is intended to perform the same computation as the method under test. But if we haven't tested doComplicatedCalculation() then how can we rely on a copy of that method to verify that it works? You can't use a logical proposition to prove itself, and you can't use a method to test itself.

Second, even if you were absolutely sure that doComplicatedCalculation() is correct, any change made to this method also has to be made to computeExpectedTestResult(). You've effectively doubled your coding effort, or, at the very least, set yourself up for a fumble-fingers cut-and-paste problem.

A better solution would be to replace the computeExpectedTestResult() invocation with a constant value that you've computed yourself:


Now, if the assertion fails, you know where to look for the problem. If the method under test changes, it's also clear where to change the expected value to match it.

Using constant values in your unit test assertions reduces the guesswork in your testing effort, and increases future comprehension and maintenance efforts.

1 Comments:

Anonymous Jeremy Hicks said...

I've come quite late (over two years late) to your excellent set of articles, but I hope that one constructive comment will be useful.

In your example code in this article, the assertion is assertEquals(result, expected);. The problem is that the arguments are the wrong way round, which can lead to a confusing message if the test fails. The assertEquals method expects its first argument to be the expected value, and the second one the actual value, and if they are not the same the message issued is "expected 1st but was 2nd".

So in your example, if the method under test returned 102, the message would be "expected 102 but was 100", which is the reverse of the truth.

Fri Mar 13, 11:56:00 AM 2009  

Post a Comment

<< Home