A while back I started a new project called ennf – Eddie’s Neural Network Framework. (Check it out at http://ennf.codeplex.com/) One of the things this framework brings along is an automatic storing of the networks in a database with the code-first Entity Framework 4.1 from Microsoft. Of course I wanted to create NUnit tests for the software as I’ll be developing this over years to come and when other people get into it, I’m bound to not have a complete overview over all the code. And it is a best practice anyway.
Unfortunately Microsoft hasn’t gotten around to implementing the framework Unit-testing friendly. One blog from a Microsoft Engineer (sorry, don’t have the link anymore) in essence said “It wasn’t the first priority”.
@Microsoft: please make unit-testability a priority on your next cycle. Thanks.
That being the case, the situation leaves you with 2 options:
- Use Moles to replace the corresponding Methods with your delegates. (see http://research.microsoft.com/en-us/projects/pex/ )
- Create your own interfaces with the same signature and wrap the Entity Framework classes in these
While Moles is a nifty idea, I ran into trouble trying to use them with Unity Framework 2.0 and the Enterprise Library. For some reason (which I didn’t research further) the unity framework suddenly didn’t work correctly anymore once I tried combining it with Moles. My guess is that the reflection somehow got messed up, but that is really just a stab in the dark. A way how to do this can be found here.
That left me with option 2 – wrapping the entity framework with my own interfaces. There are blogs aplenty around showing how to use the IDbSet interface to create unit tests. (example here or an older example here)
Be warned: that is only half the story and the blogs are quiet on anything else. Once you take that path, you end up having to slowly replace all classes with wrappers. At least if you use the Entity Framework for anything else than trivial things. The first step is to setup your T4 Templates which is fairly easy to do. And then the fun starts. First you replace the DbSet, then the DbEntityEntry and then it starts getting boring.
Well … if you want to Unit-test, then you don’t have much options. How does such wrappers look like? An example
public interface IDbMemberEntry<TEntity, TProperty> where TEntity : class
bool Equals(object obj);
Code Example 1: Interface for DbMemberEntry
class DbMemberEntryAdapter<TEntity, TProperty> : IDbMemberEntry<TEntity,TProperty> where TEntity : class
public DbMemberEntryAdapter(DbMemberEntry<TEntity, TProperty> memberEntry)
public TProperty CurrentValue
public IDbEntityEntry<TEntity> EntityEntry
public string Name
public ICollection<System.Data.Entity.Validation.DbValidationError> GetValidationErrors()
Code Example 2: Implementation for DbMemberEntry
Ok, the example isn’t fully implemented, but you get the idea. The rest is just coding …