First, assertTrue
and its relatives (assertFalse
, assertThat
) are all static methods. One would import the static method of their assertion of choice (and that lives in Assert
, so assertTrue
is shorthand for Assert.assertTrue
).
Second, the assertion takes place with respect to the object, but not as a property of it. In my mind, it does not make sense to conduct assertions to a concrete object if the assertion is an actual property on the object.
Third, when you're retrieving your result (which I presume is what you're doing), you want the answer from the concrete object you're testing. I don't understand your construct for retrieving Result
back, since what you intend to test in a unit test is just some unit of code - something small, straightforward to verify, and something that does not actively interfere with refactoring efforts.
Here's how I would normally write unit tests. Hopefully this provides you some clarification as to what I want out of my tests, and what I'd be testing.
Use case: I have written a utility to retrieve the set difference between two Lists
, with the obvious caveat that there may be duplicates. This is some code I recall putting together for another answer, but I liked it enough that I refined it, and wrote tests to ensure behavior.
public static List<Integer> difference(List<Integer> leftList, List<Integer> rightList) {
if(null == leftList || null == rightList) {
throw new IllegalArgumentException("Can't have any null parameters.");
}
if(leftList.size() < rightList.size()) {
throw new IllegalArgumentException("Left shouldn't be larger than right.");
}
List<Integer> result = new LinkedList<>();
int i = 0;
int j = 0;
while (i < leftList.size()) {
while (j < rightList.size()) {
Integer leftElement = leftList.get(i);
Integer rightElement = rightList.get(j);
if(rightElement.compareTo(leftElement) <= 0) {
// less than or equal to. Skip.
i += 1;
j += 1;
break;
}
if(rightElement.compareTo(leftElement) > 0) {
// The right-hand side is greater than the left hand side.
// Add it to the results.
result.add(leftElement);
i++;
break;
}
j++;
}
}
return result;
}
Here's what the unit tests are like. Notice how I'm asserting, in principle, one thing. It violates some principle of OO, but when you're writing tests, you want to assert behavior and results.
@Test
public void testDifference() throws Exception {
//given
List<Integer> left = Lists.newArrayList(1, 2, 3, 4, 5);
List<Integer> right = Lists.newArrayList(1, 2, 4, 5);
//when
List<Integer> result = SetUtils.difference(left, right);
//then
assertEquals(Lists.newArrayList(3), result);
}
@Test
public void testDifference2() throws Exception {
//given
List<Integer> left = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 9, 10);
List<Integer> right = Lists.newArrayList(1, 2, 4, 5, 10);
//when
List<Integer> result = SetUtils.difference(left, right);
//then
assertEquals(Lists.newArrayList(3, 6, 7, 9), result);
}
If you've continued down this far, let me illustrate one of the benefits to writing the unit tests in this behavior. If I wanted to forego the use of the while loop, and instead use foreach
, I could now perform that refactoring with confidence; the way that the unit tests are structured allows me to, at a glance, see and expect the behavior I honestly want from this code.
I couldn't honestly imagine trying to do that if the validity were a part of the static state. That would be tough to pull off.