```java bad-code stretch
/**
* A service object that (apparently) works with
* two value objects (User and Invoice).
*/
class SalesTaxCalculator {
TaxTable taxTable;
SalesTaxCalculator(TaxTable taxTable) {
this.taxTable = taxTable;
}
float computeSalesTax(User user, Invoice invoice) {
// note that "user" is never used directly
Address addr = user.getAddress();
float amount = invoice.getSubTotal();
return amount * taxTable.getTaxRate(addr);
}
}
```
```java stretch
/**
* Testing exposes the problem by the amount of work
* necessary to build the object graph, and test the
* small behavior you are interested in.
*/
class SalesTaxCalculatorTest {
SalesTaxCalculator calc = new SalesTaxCalculator(
new TaxTable()
);
Address address = new Address(
"1600 Amphitheatre Parkway..."
);
// Wiring all the needed objects together...
User user = new User(address);
Invoice invoice = new Invoice(1, new ProductX(95.00));
// ... only to be thrown away in computeSalesTax()
assertEquals(
0.09, calc.computeSalesTax(user, invoice), 0.05
);
}
```