
731
Refactoring Notes
If the objects in the fi xture are not relevant to the test, they should not be visible in
the test. Therefore, we should try to eliminate the need to create all these objects.
We could try passing in null for the Customer. In this case, the constructor checks for
null and rejects it, so we have to fi nd another way.
The solution is to replace the object that is not important to our test with a
Dummy Object. In dynamically typed languages, we could just pass in a string.
In statically typed languages such as Java and C#, however, we must pass in a
type-compatible object. In this case, we have chosen to do an Extract Interface
[Fowler] refactoring on Customer to create a new interface and then create a new
implementation class called DummyCustomer. Of course, as part of the Extract Inter-
face refactoring, we must replace all references to Customer with the new interface
name so that the DummyCustomer will be acceptable. A less intrusive option would
be to use a Test-Specifi c Subclass of Customer that adds a test-friendly constructor.
Example: Dummy Values and Dummy Objects
Here’s the same test using a Dummy Object instead of the Product name and the
Customer. Note how much simpler the fi xture setup has become!
public void testInvoice_addLineItem_DO() {
final int QUANTITY = 1;
Product product = new Product("Dummy Product Name",
getUniqueNumber());
Invoice inv = new Invoice( new DummyCustomer() );
LineItem expItem = new LineItem(inv, product, QUANTITY);
// Exercise
inv.addItemQuantity(product, QUANTITY);
// Verify
List lineItems = inv.getLineItems();
assertEquals("number of items", lineItems.size(), 1);
LineItem actual = (LineItem)lineItems.get(0);
assertLineItemsEqual("", expItem, actual);
}
Using a Dummy Object for the name of the Product was simple because it is a
string and has no uniqueness requirement. Thus we were able to use a Self-
Describing Value. We were not able to use a Dummy Object for the Product
number because it must be unique, so we left it as a Generated Value. The
Customer was a bit trickier because the LineItem’s constructor expected a non-
null object. Because this example is written in Java, the method parameter is
strongly typed; for this reason, we needed to create an alternative implemen-
tation of the ICustomer interface with a no-argument constructor to simplify
in-line construction. Because the DummyCustomer is never used, we have created
Dummy Object
Dummy
Object