Dependent Object Framework

The Dependent Object Framework (DOF) (http://sourceforge.net/projects/dof/) enables efficient JUnit testing and Test Driven Development against code that depends on objects that are persisted (e.g., database). This code was originally developed to add JUnit tests that used the real database code rather than trying to mock out all the dependencies in a large commercial enterprise product, IBM’s WebSphere Product Center.

Let’s look at a simple example. Consider that you are writing a JUnit test for invoice functionality. Your invoice needs a product record in the database. So you simply put this line at the top of your JUnit test:

Product product = (Product) DOF.require("product.13.xml");

What you have not done is pre-load the database with a SQL script. Your test is just saying “make sure that the product record 13 exists in the database and give me that object. You know that the product record will have other records that it depends on, but you only need to specify that your test requires the product record. In fact, the file “product.13.xml” is used by another test, so you don’t even need to create it.

Can it get any easier than this for specifying what your test needs on top of an unpopulated database?

The DOF makes it easy to write tests with database dependencies. Advantages include:
1. Facilitation of testing legacy enterprise code lacking JUnit tests. With the DOF, you do not need to untangle the database dependencies in order to write mock objects.
2. Easy reuse of database objects needed for unit tests.
3. Very simple to define which objects a test depends upon. Any indirect dependencies (dependencies of the dependencies) are specified in the files defining the dependent objects. Thus, a JUnit test can depend on object A, and object A might depend on object C. The test simply needs to specify object A, and the definition file for object A will specify object C.
4. Very easy to delete persistent objects created for a test. When one is tweaking tests, this is very helpful.
5. Very easy to add support for new database object types.

So how does this work?

1. You define a data file format for your object type, such as XML.

2. You write a “handler” class for this data file format. The handler class implements an interface DependentObjectHandler composed of “create(fileToLoad)”, “get(primaryKey)”, and “delete(primaryKey)”

3. You specify the mapping of the object types to the handlers, in a file called handler_mappings.properties. For example, to specify that files named like product.13.xml map to the ProductXmlFactory class:
product.xml=myPackage.ProductXmlFactory

4. You create a data file for the object you want to create, named like {objectType}.{primaryKey}.{fileExtension} such as “product.13.xml”

5. The data file contains comment lines indicating its dependencies. For example, this line indicates that the product 13 depends on the manufacturer 33 existing in the database.
<!-- $require("manufacturer.33.xml"); -->

You can download the framework including the JavaDoc and an example that uses simple XML and hsqldb here: http://sourceforge.net/projects/dof/

Please let me know if you find this useful and if you’d like to contribute. I’m working on extending the example to support hibernate. I suspect that the project might not need to change for this support.

I’m presenting this material at SD West 2008 in March:
https://www.cmpevents.com/SDw8/a.asp?option=G&V=3&id=558049

I'd like to hear if you have any comments or questions on this project.

Cheers,

Justin Gordon
justgordon at yahoo.com