Stuart Clark, a blog-less ex-colleague, good friend and climber extraordinaire asked me to write this post on his behalf. So, while I’d like to take credit for this cool idea, I have to admit it’s all his – today I’m simply playing editor.

In Linq to Sql we always work with a DataContext object (which doesn’t implement any interface) which exposes the database tables as Table<T> (which do not implement an interface either). This means it’s not possible to mock either the DataContext or the data tables without using expensive mocking software (for example, Typemock.net). So it isn’t really possible to unit test your Linq to SLQ queries without being connected to the underlying data source – not ideal. But fear not, here is a generic solution to this problem.

Consider the following interface, IDataContextWrapper.

public interface IDataContextWrapper : IDisposable
    {
        List<T> Table<T>() where T : class;
        void DeleteAllOnSubmit<T>(IEnumerable<T> entities) where T : class;
        void DeleteOnSubmit<T>(T entity) where T : class;
        void InsertOnSubmit<T>(T entity) where T : class;
        void SubmitChanges();
    }

And the DataContextWrapper class that implements this interface.

public class DataContextWrapper<T> : IDataContextWrapper where T : DataContext, new()
    {
        private readonly T db;
        private bool _disposed;
 
        public DataContextWrapper()
        {
            var t = typeof(T);
            db = (T) Activator.CreateInstance(t);
        }
 
        public DataContextWrapper(string connectionString)
        {
            var t = typeof(T);
            db = (T)Activator.CreateInstance(t, connectionString);
        }
 
        #region IDataContextWrapper Members
 
        /// <summary>
        /// Tables this instance.
        /// </summary>
        /// <typeparam name="TableName"></typeparam>
        /// <returns></returns>
        public List<TableName> Table<TableName>() where TableName : class
        {
            var table = (Table<TableName>)db.GetTable(typeof(TableName));
 
            return table.ToList();
        }
 
        public void DeleteAllOnSubmit<Entity>(IEnumerable<Entity> entities) where Entity : class
        {
            db.GetTable(typeof(Entity)).DeleteAllOnSubmit(entities);
        }
 
        public void DeleteOnSubmit<Entity>(Entity entity) where Entity : class
        {
            db.GetTable(typeof(Entity)).DeleteOnSubmit(entity);
        }
 
        public void InsertOnSubmit<Entity>(Entity entity) where Entity : class
        {
            db.GetTable(typeof(Entity)).InsertOnSubmit(entity);
        }
 
        public void SubmitChanges()
        {
            db.SubmitChanges();
        }
        
        #endregion
 
        // Dispose Members...
}

This generic class can be instantiated with any LINQ to SQL DataContext and the interface is implemented directly against this.

We could now write a controller class that has an IDataContextWrapper property,

internal class CustomerController
    {
        public IDataContextWrapper DataContext { get; set; }
 
        public IEnumerable<Customer> GetCustomersWithFirstName(string firstName)
        {
            var customers = from customer in DataContext.Table<Customer>()
                            where customer.FirstName == firstName
                            select customer;
 
            return customers;
        }
    }

and use with a LINQ to SQL DataContext created for the AdventureWorks database.

var controller = new CustomerController();
controller.DataContext = new DataContextWrapper<AdventureWorksDataContext>();
 
var results = controller.GetCustomersWithFirstName("John");

Note the change in syntax for our LINQ query in CustomerController where the query works against the IDataContextWrapper interface rather than against the actual DataContext.

We are now ready to create a mock version of IDataContextWrapper that works against a MockDatabase rather than a DataContext (I haven’t included the details here but it is essentially an in memory representation of database tables – check out the download).

public class MockDataContextWrapper : IDataContextWrapper
{
    private readonly MockDatabase _mockDatabase;
 
    public MockDataContextWrapper(MockDatabase database)
    {
        _mockDatabase = database;
    }
 
    #region IDataContextWrapper Members
 
    public List<T> Table<T>() where T : class
    {
        return (List<T>)_mockDatabase.Tables[typeof(T)];
    }
 
    public void DeleteAllOnSubmit<T>(IEnumerable<T> entities) where T : class
    {
        foreach (var entity in entities)
        {
            Table<T>().Remove(entity);
        }
    }
 
    public void DeleteOnSubmit<T>(T entity) where T : class
    {
        Table<T>().Remove(entity);
    }
 
    public void InsertOnSubmit<T>(T entity) where T : class
    {
        Table<T>().Add(entity);
    }
 
    public void SubmitChanges()
    {
    }
 
    public void Dispose()
    {
    }
 
    #endregion
}
}

We can now instantiate our CustomerController class against an in memory database representation,

var controller = new CustomerController();
controller.DataContext = new MockDataContextWrapper(new ExampleMockDatabase());
 
var results = controller.GetCustomersWithFirstName("John");

So we now have a way to test our LINQ to SQL queries within our CustomerController class without relying on a database bound DataContext.

You can download the full source from here.

So what do you reckon? I’m sure Stu will be glad to receive any feedback.

kick it on DotNetKicks.com