Tigraine

Daniel Hoelbling-Inzko talks about programming

Big>Days 2009 Code

Posted by Daniel Hölbling on March 23, 2009

I already picked on the Big>Days 2009 source today, and since it’s open and there, why not just write a little patch.

Without having to go too far into the code I thought a perfect spot to start would be the DataAccessFactory that should return test-dummys during tests while serving real objects otherwise.

What I didn’t like was the fairly repetitive code of checking if it’s in dummy mode and returning the appropriate object:

public static ICustomerAccess GetCustomerAccess()
{
    if (UseDummy)
        return new DataAccessDummy();
    return new CustomerDataAccess();
}

This gets repeated for every factory method and is a perfect example of a DRY violation.

I figured since we don’t want to touch calling code (and the UseDummy was never set anywhere), best way to go would be to simply create a interface for the factory:

public interface IDataAccessFactory
{
    ICustomerAccess GetCustomerAccess();
    ILocationAccess GetLocationAccess();
    IMachineTypeAccess GetMachineTypeAccess();
    IRentalServiceAccess GetRentalServiceAccess();
    IResourceAccess GetResourceAccess();
}

I then created two implementations of this, one for the TestDummy and one for the real thing (called RealDataAccessFactory) so I don’t need to check the UseDummy field any more.

Now the actual static factory can instantiate the real object by default and have a method on it to set another IDataAccessFactory implementation during runtime:

public static class DataAccessFactory
{
    private static IDataAccessFactory dataAccessFactory = new RealDataAccessFactory();

    public static IDataAccessFactory Implementation     {         get { return dataAccessFactory; }         set { dataAccessFactory = value; }     }

    public static ICustomerAccess GetCustomerAccess()     {         return dataAccessFactory.GetCustomerAccess();     }

    public static ILocationAccess GetLocationAccess()     {         return dataAccessFactory.GetLocationAccess();     }

    public static IMachineTypeAccess GetMachineTypeAccess()     {         return dataAccessFactory.GetMachineTypeAccess();     }

    public static IRentalServiceAccess GetRentalServiceAccess()     {         return dataAccessFactory.GetRentalServiceAccess();     }

    public static IResourceAccess GetResourceAccess()     {         return dataAccessFactory.GetResourceAccess();     } }

During production nothing changes, but in a unit test scenario I can pass a fake DataAccessFactory into the static factory and swap the whole implementation (enabling me to use Rhino.Mocks or whatever mocking framework I like instead of writing TestDummys myself).

This way we can even have the TestDummy class living inside the test assembly instead of littering the production assembly.

A test now may look like this:

[Fact]
public void Module_CallsFactoryForILocationAccess()
{
    DataAccessFactory.Implementation = MockRepository.GenerateMock<IDataAccessFactory>();

    var module = new Module();     module.DoSomething(); //This should call the Factory to retrieve a ILocationAccess

    DataAccessFactory.Implementation.AssertWasCalled(p => p.GetLocationAccess()); }

As you can see, we now have complete control over the factory during testing, without affecting the rest of the code in any way.
Another sideeffect of this is that the static DataAccessFactory or the actual DataAccessFactory implementation has no need to change if we need to make changes to the DummyFactory.

Filed under net, programmierung
comments powered by Disqus

My Photography business

Projects

dynamic css for .NET

Archives

more