List<FlightLeg> legs = new ArrayList<FlightLeg>();
legs.add(new FlightLeg(fooCity, start, barCity, end));
flight = new Flight(legs, new BigDecimal(40));
try {
flight.getTotalTravelTime();
fail("Should have thrown exception");
} catch(IllegalArgumentException e) {
assertEquals("Start date must be before end date", e.getMessage());
}
}
private List<FlightLeg> createSingleLeg() {
List<FlightLeg> legs = new ArrayList<FlightLeg>();
legs.add(new FlightLeg(fooCity, new Date(), barCity, new Date()));
return legs;
}
}
Private Methods
As you may have noticed, we didn’t write any tests that explicitly test private methods of the
class. Certainly private methods are internal implementation-specific methods and are not
part of the public API of the class. We write tests to test how the object behaves, from the per-
spective of a client of the class. This is an important point about unit tests, because they force
the test writer (who should be the same person who creates the class) to think like a client of
the class. The test author quickly begins to ask questions such as, How would I want to use this
class? and What do I need from this class to get the job done? Writing unit tests can quickly
expose any weaknesses of the class in terms of usability, which can be very beneficial.
How Do I Know When the Test Is Done?
A common question that pops up when writing unit tests is “How do I know If I've written
enough tests?” There isn’t a quick and easy answer to this, but a few guidelines and tools can
help you determine how much of the code is actually tested.
The first guideline: Test your methods with values you don’t expect to receive. To begin,
test your methods with zeros and nulls as input values. Your method should gracefully handle
this case, which we will call an edge case. Edge cases are conditions that might expose a prob-
lem because they are near or at the edge of acceptable values. Examples of this are zero, null,
infinity, and conditions that are defined by your business logic as maximum or minimum.
Creating tests for all of these edge cases is a good start toward completeness.
Once you have tests for the edge cases, simply write tests for the common cases. These
test scenarios should use values that are representative of conditions that will occur most fre-
quently. You do not need to test every single value (a lot of real numbers are out there), so use
your best judgment here. The edge cases are certainly more important to test, because they
are most often forgotten or neglected by the code, but the common case(s) should always be
tested as well.
288 CHAPTER 10 ■TESTING SPRING MVC APPLICATIONS