Unit Testing Domain Objects Without Public Constructors and Setters

How to unit test a domain object that is instantiated and populated solely through a persistence API as Hibernate? Having such domain objects isn’t uncommon in database-centric solutions. The organization might have other systems, roles or employees entering and governing these data. In Domain Driven Design, the domain objects are our most important entity and should reflect the real world. If the application have no need for creating new instances of a domain class, the class definition shouldn’t include public constructors. If it contains read-only data, the fields should as well be private, without public setters. My experience is ” if you provide the opportunity for a developer to misuse your domain object, it will be misused, sooner than later”. But to test the domain objects and logic in isolation of the persistence layer, you’d have to add public constructors and/or setters, or modify them to public access. To me, a good, restrictive domain model and unit tests are both extremely important. What should you do? That’s my punchline. Read on!

Ah sorry. Reflection sucks for this purpose. I’ve deleted the previous solution. The test became resistors of change! I’ve concluded it’s an anti-pattern. But I have, with great success, solved the problem at hand in way with package protected setters. That is, create a MyDomainObjectFactory.class in test-scope, and ask for your domain object in a given legal state (legal – as you BL may populate it). Be strict on your domain objects, public setters are monsters. They add permutations of states!

Additional excellent rule of thumb. Never write new in your tests (except for testing the domain object itself). Always ask for it from the factory. Then you’ll have one place to refactor it. You don’t want to refactor a hundred tests if you only change your constructor. That’s a robust test!

Database test data is also a bitch. I through them all away, used the factories to ask for the object, persist it, and test on it. It’s fast if you’re using an in-memory database as hsqldb. And you may change your application fast, really fast.

MyD myd = super.persist(MyDomainObjectFactory.createMyObjectInState());

then test on myd. (implement persist in a superclass).

Hmm, yes. This post is old. I’ll write a new one about these subjects. Let me now if you read this and wanted more.


About Ole Morten Amundsen

Developer, programmer, entrepreneur. Java, .Net, ruby, rails, agile, lean. Opinionated enthusiast!
This entry was posted in hibernate, Java and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s