« 6. Basic Pattern - #3 Domain Test Object (DTO) | Main | 4. Basic Pattern #1 - Template »
December 22, 2004
5. Basic Pattern #2 - Object Genie
Relieve tests from having to instantiate and initialize common non-trivial objects by having them ask for those objects from a central authority that grants objects in a pre-defined state. This pattern is also known as ObjectMother.8
There are many occasions during testing when multiple tests will require the same object and then each proceed to interact with it in different ways. If it is a simple object, each test can just instantiate it normally (SomeObject object = new SomeObject();) However, there are many occasions where the object that is needed by tests is cumbersome to instantiate or initialize.
The Object Genie consolidates the construction and initialization of that object to just one place, thereby reducing future maintenance costs and facilitating the creation of new tests. If the way an object is instantiated or initialized ever changes, the update would only be done in the Object Genie and the test cases that use that Object Genie would be unaffected.
In our shopping cart application, multiple tests (e.g. test deleting an item from a cart, test the checkout process, test processing a coupon) require a shopping cart with a few items in it. Without the Object Genie pattern, each test would have to re-create and re-populate the shopping cart, increasing code duplication and maintenance costs. Using an Object Genie, a test can request a non-empty shopping cart and then proceed with testing. The Object Genie handles the instantiation of the shopping cart and populates it. In Figure 5, the Object Genie populates the shopping cart with two items (orange juice and cereal).
Figure 5: Defining a shopping cart Object Genie.
public class CartGenie {
public static ShoppingCart getNonEmptyCart() {
ShoppingCart shoppingCart = new ShoppingCart();
Item ojItem = searchForItem("orange juice");
shoppingCart.add(ojItem);
Item cerealItem = searchForItem("cereal");
shoppingCart.add(cerealItem);
return shoppingCart;
}
private static Item searchForItem(String pItemId) {
//search for the item based on the item id
}
}
Each test would call CartGenie.getNonEmptyCart() to receive an initialized shopping cart and then proceed with the details of the test. The tests would be decoupled from having to know how a shopping cart is instantiated and populated, thereby reducing future maintenance costs (see Dumb Test in Section II: General Design Principles).
Posted by Misha Rybalov at December 22, 2004 10:31 PM