Unit Testing DbContext

Ask yourself a single question: What are you going to test?

You mentioned FakeContext and Mocking the context – why to use both? Those are just different ways to do the same – provide test only implementation of the context.

There is one more bigger problem – faking or mocking context or set has only one result: You are not testing your real code any more.

Simple example:

public interface IContext : IDisposable
{
    IDbSet<MyEntity> MyEntities { get; }
}

public class MyEntity
{
    public int Id { get; set; }
    public string Path { get; set; } 
}

public class MyService
{
    private bool MyVerySpecialNetMethod(e)
    {
        return File.Exists(e.Path);
    }

    public IEnumerable<MyEntity> GetMyEntities()
    {
        using (IContext context = CreateContext())
        { 
            return context.MyEntities
                .Where(e => MyVerySpecialNetMethod(e))
                .Select(e)
                .ToList();
        }
    }
}

Now imagine that you have this in your SUT (system under test – in case of unit test it is an unit = usually a method). In the test code you provide FakeContext and FakeSet and it will work – you will have a green test. Now in the production code you will provide a another derived DbContext and DbSet and you will get exception at runtime.

Why? Because by using FakeContext you have also changed LINQ provider and instead of LINQ to Entities you are running LINQ to Objects so calling local .NET methods which cannot be converted to SQL works as well as many other LINQ features which are not available in LINQ to Entities! There are other issues you can find with data modification as well – referential integrity, cascade deletes, etc. That is the reason why I believe that code dealing with context / LINQ to Entities should be covered with integration tests and executed against the real database.

Leave a Comment