List lineItems = invoice.getLineItems();
if (lineItems.size() == 1) {
LineItem actItem = (LineItem) lineItems.get(0);
assertEquals("inv", invoice, actItem.getInv());
assertEquals("prod", product, actItem.getProd());
assertEquals("quant", 5, actItem.getQuantity());
assertEquals("discount", new BigDecimal("30"),
actItem.getPercentDiscount());
assertEquals("unit price",new BigDecimal("19.99"),
actItem.getUnitPrice());
assertEquals("extended", new BigDecimal("69.96"),
actItem.getExtendedPrice());
} else {
assertTrue("Invoice should have 1 item", false);
}
A simple problem to fi x is the obtuse assertion on the very last line. Calling
assertTrue with an argument of false should always result in a test failure, so
why don’t we say so directly? Let’s change this to a call to fail:
List lineItems = invoice.getLineItems();
if (lineItems.size() == 1) {
LineItem actItem = (LineItem) lineItems.get(0);
assertEquals("inv", invoice, actItem.getInv());
assertEquals("prod", product, actItem.getProd());
assertEquals("quant", 5, actItem.getQuantity());
assertEquals("discount", new BigDecimal("30"),
actItem.getPercentDiscount());
assertEquals("unit price",new BigDecimal("19.99"),
actItem.getUnitPrice());
assertEquals("extended", new BigDecimal("69.96"),
actItem.getExtendedPrice());
} else {
fail("Invoice should have exactly one line item");
}
We can think of this move as an Extract Method [Fowler] refactoring, because we
are replacing the Stated Outcome Assertion (see Assertion Method on page 362)
with a hard-coded parameter with a more intent-revealing call to a Single Out-
come Assertion (see Assertion Method) method that encapsulates the call.
Of course, this set of assertions suffers from several more problems. For exam-
ple, why do we need so many of them? It turns out that many of these assertions
are testing fi elds set by the constructor for the LineItem, which is itself covered by
another unit test. So why repeat these assertions here? It will just create more test
code to maintain when the logic changes.
One solution is to use a single assertion on an Expected Object (see State Veri-
fi cation on page 462) instead of one assertion per object fi eld. First, we defi ne an
object that looks exactly how we expect the result to look. In this case, we create
Cleaning Up the Test
xlvii