Friday, February 15, 2008

TypeMock - Allows Me Not To Decouple Too Far

I just had a situation today that emphasized to me why TypeMock can be so useful.

Design

IDomainChangeTrackingService interface in a domain assembly implemented by an infrastructure service class (DomainChangeTrackingService) in another assembly. We use DI with a ServiceLocator to get the implementation of the service into the domain.
Initially the DomainChangeTrackingService just persists the DomainChangeMessages passed to it, so all it does is call out to the DomainChangeMessageRepository:

public class DomainChangeTrackingService : IDomainChangeTrackingService
{
public void ProcessMessage(DomainChangeMessage message)
{
new DomainChangeMessageRepository().Save(message);
}
}
Testing

I've already written integration tests for the DomainChangeMessageRepository so when testing the DomainChangeTrackingService a single interaction test that just checks it calls the DomainChangeMessageRepository would be enough.

The problem was that DomainChangeTrackingService creates and uses the DomainChangeMessageRepository.

Without TypeMock I'd probably have handled this with more decoupling. I'd probably have made the repository implements an interface and the implementation of that interface is injected into DomainChangeTrackingService (or it could get it from the service locator).

This could be useful in the future but I'm certainly not wanting to worry about it right now and certainly isn't decoupling I'd be looking for. For me this is one the situations where TypeMock is great, I can interaction test DomainChangeTrackingService without having to change my design.

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

5 comments:

  1. Anonymous10:32 pm

    That's fine, but I love to stub out repositories in acceptance tests and development mode. I'd still opt for DI there. Using TypeMock with the tight coupling to the repository eliminates the option to easily stub the repository and/or to reuse that code in another context.

    Give and take Colin.

    ReplyDelete
  2. it does not eliminate anything. it's a choice. you could still put DI there if you wanted, you are just not forced to do it.

    ReplyDelete
  3. Anonymous7:08 am

    I agree with Roy, It doesn't eliminate any option to easily stub the repository - The opposite - You can easily (without over-designing) stub the Repository - This is exactly CJ's example.

    Reusing the code is also really easy - just use the repository class.

    As you say, having a way to CHANGE and Inject the repository implementation at runtime from an external class/resource is not supporting, but hey that is a big YAGNI - once there is a compelling business reason to do so, it is also really easy to REFACTOR the code - and the test will still pass.

    ReplyDelete
  4. Maybe I am misunderstanding something but ...

    perhaps the problem here is the service which is only really there to implement the interface for the message handling?

    Why can't the repository itself subscribe to the domain changes? Then you are just left with an integration test that it writes them properly.

    ReplyDelete
  5. Thats a good suggestion and it's one we considered. In the end we liked seperating the service and repository, though to be fair either design sits well with me.

    What I love about TypeMock though is that in these sorts of cases I can have one class or two and not end up in a situation where I need to jump through lots of hoops to test.

    ReplyDelete