views:

214

answers:

4

What is an ObjectMother and what are common usage scenarios for this pattern?

+2  A: 

Just a catchy synonym for a GoF Factory, according to Martin Fowler.

duffymo
+6  A: 

ObjectMother starts with the factory pattern, by delivering prefabricated test-ready objects via a simple method call. It moves beyond the realm of the factory by facilitating the customization of created objects, providing methods to update the objects during the tests, and if necessary, deleting the object from the database at the completion of the test.

Some reasons to use ObjectMother:
* Reduce code duplication in tests, increasing test maintainability
* Make test objects super-easily accessible, encouraging developers to write more tests.
* Every test runs with fresh data.
* Tests always clean up after themselves.

(http://c2.com/cgi/wiki?ObjectMother)

David Brown
+2  A: 

See "Test Data Builders: an alternative to the Object Mother pattern" for an argument of why to use a Test Data Builder instead of an Object Mother. It explains what both are.

cwash
That article is now hosted at www.natpryce.com.
Nat
Just updated link...
cwash
Thanks for the article, BTW.
cwash
A: 

As stated elsewhere, ObjectMother is a Factory for generating Objects typically (exclusively?) for use in Unit Tests.

Where they are of great use is for generating complex objects where the data is of no particular significance to the test.

Where you might have created an empty instance below such as

    Order rubishOrder = new Order("NoPropertiesSet");
    _orderProcessor.Process(rubishOrder);

you would use a sensible one from the ObjectMother

    Order motherOrder = ObjectMother.SimpleOrder();
    _orderProcessor.Process(motherOrder);

This tends to help with situations where the class being tested starts to rely on a sensible object being passed in.

For instance if you added some OrderNumber validation to the Order class above, you would simply need to instantiate the OrderNumber on the SimpleObject class in order for all the existing tests to pass, leaving you to concentrate on writing the validation tests.

If you had just instantiated the object in the test you would need to add it to every test (it is shocking how often I have seen people do this).

Of course this could just be extracted out to a method, but putting it in a separate class allows it to be shared between multiple test classes.

Another recommended behaviour is to use good descriptive names for your methods, to promote reuse. It is all to easy to end up with one object per test, which is definitely to be avoided. It is better to generate objects that represent general rather than specific attributes and then customise for your test. For instance ObjectMother.WealthyCustomer() rather than ObjectMother.CustomerWith1MdollarsSharesInBigPharmaAndDrivesAPorsche() and ObjectMother.CustomerWith1MdollarsSharesInBigPharmaAndDrivesAPorscheAndAFerrari()

Modan