
195
public void testAddItemQuantity_severalQuantity_v12(){
// Set Up Fixture
Customer cust = createACustomer(new BigDecimal("30"));
Product prod = createAProduct(new BigDecimal("19.99"));
Invoice invoice = createInvoice(cust);
// Exercise SUT
invoice.addItemQuantity(prod, 5);
// Verify Outcome
LineItem expected = new LineItem(invoice, prod, 5,
new BigDecimal("30"), new BigDecimal("69.96"));
assertContainsExactlyOneLineItem(invoice, expected);
}
This specifi c example isn’t so bad because there aren’t very many literal values. If
we aren’t good at doing math in our heads, however, we might miss the relation-
ship between the unit price ($19.99), the item quantity (5), the discount (30%),
and the total price ($69.96).
Root Cause
Hard-Coded Test Data occurs when a test contains a lot of seemingly unrelated
Literal Values. Tests invariably require passing data to the SUT. The data used in
the fi xture setup and exercise SUT phases of the Four-Phase Test defi ne the pre-
conditions of the SUT and infl uence how it should behave. The post-conditions
(the expected outcomes) are refl ected in the data passed as arguments to the
Assertion Methods in the verify outcome phase of the test. When writing tests,
the path of least resistance is to use whatever methods are available (on the SUT
and other objects) and to fi ll in all parameters with values, whether or not they
are relevant to the test.
When we use “cut-and-paste” reuse of test logic, we fi nd ourselves replicat-
ing the literal values to the derivative tests.
Impact
It is hard to achieve Tests as Documentation if the tests contain many seemingly
random bits of Obscure Test that don’t clearly link the pre-conditions with the
post-conditions. A few literal parameters might not seem like a bad thing—after
all, they don’t require us to make that much more effort to understand a test. As
the number of literal values grows, however, it can become much more diffi cult
to understand a test. This is especially true when the signal-to-noise ratio drops
dramatically because the majority of the values are irrelevant to the test.
The second major impact occurs when collisions between tests occur because
the tests are using the same values. This situation happens only when we use a
Shared Fixture because a Fresh Fixture strategy shouldn’t litter the scene with
any objects with which a subsequent test can collide.
Obscure Test
Obscure
Test