Ron Jacobs

Windows Workflow Foundation

Mocking the TableGateway pattern

Mocking the TableGateway pattern

  • Comments 3

I've been writing some new Hands On Labs for the WCF REST Starter Kit and as I mentioned previously on my blog I want to include unit tests.  Several people commented on my previous efforts and pointed out that the tests I included with the REST Collection lab are really integration tests because they use the HTTP stack to pass messages from a client to the REST Service.

So this time I've decided to build out both an integration test layer and a unit test layer.  My goal for the unit test layer was to exercise the service without the HTTP stack or the database.  What this means is that I had to come up with a way to mock the database layer.

In my previous code I was using static methods on the CohoDB class backed up by LINQ to SQL classes.  This time I took a new approach that uses the Table Gateway pattern with a twist.  I wanted to use the Factory pattern with the gateway and provide a way to substitute the factory with a Mock factory that I could use when unit testing.  Sound confusing?  Here is the pattern.

First you need to define an interface for the TableGateway

    public interface IWineGateway
    {
        WineData GetWine(int wineID);
        IEnumerable> GetWines(int startIndex, int pageSize);
        IEnumerable> GetAllWines();
        WineData AppendWine(WineData wineData);
        WineData UpdateWine(int wineID, WineData wineData);
        WineData PutWine(int wineID, WineData wineData, out bool inserted);
        void DeleteWine(int wineID);
    }

Next you need an interface for the Factory

    public interface IWineGatewayFactory
    {
        IWineGateway CreateWineGateway();
    }

Now you need to implement your interfaces, the factory and the table gateway with classes. To make it simple to create the table gateway I use a static property that defines the factory that will be used (it defaults to the factory that creates the real class) and a static method to create the gateway.

    public class WineGateway : IWineGateway
    {
        static IWineGatewayFactory _factory;

        public static IWineGatewayFactory Factory
        {
            get
            {
		// Default to the WineGatewayFactory
                if (_factory == null)
                {
                    _factory = new WineGatewayFactory();
                }

                return _factory;
            }
            set
            {
		// Unit tests can set a MockFactory if they like
                _factory = value;
            }
        }

        public static IWineGateway Create()
        {
            return Factory.CreateWineGateway();
        }

Now when I need a table gateway I can call the static Create method and get one. However it still wasn't quite as convenient as I wanted so in the consuming service I added a property of type WineGateway that automatically created it when I needed it.

        IWineGateway _winesGateway;

        IWineGateway WinesGateway 
        {
            get
            {
                if (_winesGateway == null)
                    _winesGateway = WineGateway.Create();

                return _winesGateway;
            }
        }

This allows me to make calls into the table gateway with one simple line of code, just like I did before using the static methods on CohoDB

        protected override WineData OnGetItem(string id)
        {
            Int32 wineID;

            if (!Int32.TryParse(id, out wineID))
            {
                throw new WebProtocolException(HttpStatusCode.BadRequest);
            }

            return WinesGateway.GetWine(wineID);
        }

Beautiful isn't it? But wait there's more! What about when unit testing? No problem, just inject the Mock factory instead and create a class that implements the gateway interface

        [TestInitialize()]
        public void MyTestInitialize()
        {
            // Setup the WineGateway to use the mocks
            WineGateway.Factory = new MockWineGatewayFactory();
        }

Now my project has both integration and true unit tests. I haven't posted it on the web yet because I've more cleanup work to do and need to finish writing the docs but it's going to be great!

  • PingBack from http://www.codedstyle.com/mocking-the-tablegateway-pattern-2/

  • Factories are great when you have many implementations of the same interface, but when you just need to swap out a dependency for testing it seems like overkill, I prefer the following pattern.

    <code>

    public class WineGateway : IWineGateway

    {

     IRepository _repository;

     public void WineGateway(IRepository repository)

     {

       _repository = repository;

     }

     public void WineGateway() : this(new DefaultRepository())

     {

     }

     // Implementation...

    }

    // normal usage

    var wineGateway = new WineGateway();

    // test usage

    var wineGateway = new WineGateway(new TestRepository());

    // or alternatively using Moq

    var wineGateway = new WineGateway(CreateMockRepository().Object);

    </code>

    I can use the same method to swap out any dependency that WineGateway uses that is not directly related to the unit test I am writing (for example I could also pass an ILog or an INotificationService in the constructor).

    An added benefit is that it is only a small step to start using Dependency Injection container (IOC).

    <code>

    var wineGateway = container.Get<IWineGateway>();

    </code>

  • Dude - that is brilliant.  I'm going to use that method instead.  It really simplifies things.

Page 1 of 1 (3 items)