Wednesday, August 3, 2011

Entity Framework is infinitely testable

Where does Entity Framework clearly trumps NHibernate? On unit testing :-)

Entity Framework's non-error decision for mocked IQueryable makes it more unit testing-friendly than NHibernate

Given this repository interface:

public interface IRepository<Ent> where Ent : class
{
    IQueryable<Ent> All { get; }
    void Save(Ent ent, byte[] version);
    void VersionedDelete(object id, byte[] version);
    Ent LoadStub(object id);

    string PrimaryKeyName { get; set; }
    string VersionName { get; set; }

}


Dependency Injection:
ninjectKernel.Bind<IRepository<Movie>>().To<FakeRepository<Movie>>();


If you pass a mocked object to All property, NHibernate Fetch extension methods will have a runtime error:

public class MovieController : Controller
{
    IRepository<Movie> _rm = null;

    public HomeController(IRepository<Movie> rm)
    {            
        _rm = rm;
    }

    public ViewResult Index()
    {        
        return View(_rm.All.FetchMany(x=> x.Quotes).ToList());    // NHibernate FetchMany will complain
    }    
}    

NHibernate's runtime error:
There is no method 'FetchMany' on type 'NHibernate.Linq.EagerFetchingExtensionMethods' that matches the specified arguments



Whereas in Entity Framework, this will not output any error:
public class MovieController : Controller
{
    IRepository<Movie> _rm = null;

    public HomeController(IRepository<Movie> rm)
    {            
        _rm = rm;
    }

    public ViewResult Index()
    {        
        return View(_rm.All.Include(x=> x.Quotes).ToList()); // Entity Framework will not complain
    }    
}    

In my mind, any self-respecting ORM that facilitates fetching strategies, should not balk at mocked IQueryable; an ORM's fetching strategies API should silently ignore mocked IQueryable. Fetching strategies does not affect program logic, these are database optimization hints, and as such, does not have anything to do with program correctness. These APIs shouldn't throw exceptions, otherwise unit testing will be impossible.

No comments:

Post a Comment