Asserting minimums and maximums in Java test classes with org.testframe
Assert Equals is the most frequently used assertion in any unit testing framework for Java. And it’s called the same thing in JUnit, TestNG and org.testframe: assertEquals()
.
I’ve certainly written my share of unit tests with Assert Equals. Though not as frequently, I’ve also found myself writing JUnit tests with assertions like
assertTrue(maximum > actual);
or
assertTrue(account.getBalance().compareTo(SavingsAccount.MINIMUM_BALANCE)
>= 0);
Remember that Java does not allow operator overloading, aside from the special case of String
concatenation.
Asserting minimums and maximums on integer primitives is easy enough. With reference types, like whatever we’re using to represent amounts of money (we should not be using floating point primitives), it gets kind of clunky. I think I wrote the correct assertion for the minimum account balance assertion, but I could just as easily have gotten it wrong.
So as I was working on the assertions library for the org.testframe testing framework, I decided to put in assertions for minimums and maximums.
Now, with the imports
import static org.testframe.api.Asserters.assertMaximum;
import static org.testframe.api.Asserters.assertMinimum;
we can rewrite the earlier example assertions as
assertMaximum(actual, maximum);
and
assertMinimum(SavingsAccount.MINIMUM_BALANCE, actual);
Note that the parameter actual
goes first for Assert Maximum and second for Assert Minimum. I hope this doesn’t confuse anyone. IntelliJ IDEA and newer versions of Apache NetBeans might alert you if you mix these up.
In both cases, the optional message parameter msg
(of type String
) goes third, like it might in JUnit 5 or later, not first like it would have in JUnit 4 or earlier.
You can use Assert Minimum and Assert Maximum on integer primitives, on floating point primitives (though with lots of caveats) and on any type T
implementing Comparable<T>
.
It’s okay if you think the improvement is negligible in the first example. But in the second example, the improvement is quite significant.
Assert Minimum and Assert Maximum assertions are much easier to write than JUnit or TestNG Assert True assertions on the result of the compareTo()
function, and also much easier for other programmers to read and understand.
Another advantage of Assert Minimum and Assert Maximum over Assert True is that you don’t have to write custom messages to get helpful test failure explanations.
In the first run of the second example, suppose that actual
is $93.50 (USD) and MINIMUM_BALANCE
is $100.00. If you don’t write a custom message, when the test fails, it will still give you the helpful explanation that
Value $93.50 [was] expected to be at least $100.00
It’s still important to review the test failure explanations and verify that your tests fail the first time for the reasons that you thought they would fail.
The org.testframe test runner is for now only available on the command line. None of the integrations with Apache NetBeans, Eclipse or IntelliJ IDEA are ready yet. But it’s perfectly valid to use org.testframe assertions in test classes for the JUnit or TestNG test runner to run.
org.testframe is available from the website testframe.org. You can download a JAR file, source and documentation from GitHub.