
198
Chapter 15 Code Smells
Flight firstFlight = createFlight();
Flight secondFlight = createConnectingFlight(
firstFlight, LEGAL_CONN_MINS_SAME);
flightMgntStub.expects(once()).method("getFlight")
.with(eq(firstFlight.getFlightNumber()))
.will(returnValue(firstFlight));
flightMgntStub.expects(once()).method("getFlight")
.with(eq(secondFlight.getFlightNumber()))
.will(returnValue(secondFlight));
// exercise
FlightConnAnalyzer theConnectionAnalyzer =
new FlightConnAnalyzer();
theConnectionAnalyzer.facade =
(FlightManagementFacade)flightMgntStub.proxy();
FlightConnection actualConnection =
theConnectionAnalyzer.getConn(
firstFlight.getFlightNumber(),
secondFlight.getFlightNumber());
// verification
assertNotNull("actual connection", actualConnection);
assertTrue("IsLegal", actualConnection.isLegal());
}
Sometimes we may be forced to interact with the SUT indirectly because we
cannot refactor the code to expose the logic we are trying to test. In these cases,
we should encapsulate the complex logic forced by Indirect Testing behind suit-
ably named Test Utility Methods. Similarly, fi xture setup can be hidden behind
Creation Methods and result verifi cation can be hidden by Verifi cation Methods
(see Custom Assertion). Both are examples of SUT API Encapsulation (see Test
Utility Method).
public void testAnalyze_sameAirline_LessThanConnLimit()
throws Exception {
// setup
FlightConnection illegalConn =
createSameAirlineConn( LEGAL_CONN_MINS_SAME - 1);
FlightConnectionAnalyzerImpl sut =
new FlightConnectionAnalyzerImpl();
// exercise SUT
String actualHtml =
sut.getFlightConnectionAsHtmlFragment(
illegalConn.getInboundFlightNumber(),
illegalConn.getOutboundFlightNumber());
// verification
assertConnectionIsIllegal(illegalConn, actualHtml);
}
The following Custom Assertion hides the ugliness of extracting the business
result from the presentation noise. It was created by doing a simple Extract Method
[Fowler] refactoring on the test. Of course, this example would be more robust
Obscure
Test