Tuesday, August 21, 2007

The Domain And Testing Dependent Layers

I've blogged seperately about the arguments for mocking domain classes when testing the domain itself.

However we also need to consider how to deal with situations where we want to be able to mock out the domain when testing another layer, in particular we need to consider it because Ayende has just posted a good blog article that relates to the topic.

I'll take the example that I put in Ayende's blog. Lets say I have an application layer service that calls to a repository, then to an infrastructure service, then into a domain service/entity and then returns. I want to test the application layer service. In that case I can inject in the repository and infrastructure service to do interaction testing, but would you also inject the domain service/entity.

I think there are a couple of options:

  1. Interfaces - On any domain objects we need to mock.
  2. Virtual members - Any member we need to mock would be virtual.
  3. No Domain Mocking - Don't mock domain classes when testing other layers.
  4. TypeMock - Oh dear, into the lions den....

Interfaces

An interface on every domain object that we need to mock, sure its an option that some people go for but I'm with the group that argues you should only use interfaces in your domain if they are useful. I've blogged about this before but do I really want to be able to replace one Customer with another, probably not so its not a useful extension point to introduce and it ends up introducing complexity I don't need.

We've also gone for a pure (or as pure as we can get) persistence ignorant approach, so I don't want to then have to mess with my domain to get it to fit in with IoC and mocking frameworks.

Virtual Members

Interfaces are not the only way to mock domain objects, Rhino Mocks can mock virtual members too and since most of our aggregate roots are lazy loadable their members are virtual (NHibernate requires this).

This would seem to me to be a half baked solution, if we're going to mock why not use TypeMock.

TypeMock

It is a hugely powerful tool and you can misuse it. However in this case we'd have chosen to use it in a way that lets us maintain the design we want, which to me is an acceptable useage.

No Domain Mocking

Should be an option, why not let the Application layer service call into the domain service/entity.

Our domain is POCO and in fact very rarely calls out to the repositories directly. This isn't the way everyone goes as can be seen here and here.

We can get away with this thanks to NHibernate, in fact the only time our domain classes go to repositories to get reference data and when we go with that approach we hide it behind a Registry/Service Locator. By and large this works fine, where it doesn't we use a special coordination layer, part of the domain but with different responsibilities.

So using the domain should be simple.

Summary

So far we haven't needed to mock the domain classes when testing at a higher level, if we do I'm thinking that using TypeMock is a good option.

Share This - Digg It Save to del.icio.us Stumble It! Kick It DZone

No comments:

Post a Comment