Tuesday, March 01, 2011

EF CTP5 And Unit Testing

Using Entity Framework Code First CTP5 its quite easy to write and unit test your repositories. However test should still be written against the mappings of the actual database. It would be best to split the tests that write to the database from the tests that read into a different class

Just Create a class that inherits from DropCreateDatabaseAlways<T> override the seed method to create insert the values you want.
   1: public class DBContextInitializer : DropCreateDatabaseAlways<EntityContext>
   2: {
   3:     protected override void Seed(EntityContext context)
   4:     {
   5:         ProductDummies.GetAllProducts().ForEach(p => context.Set<Product>().Add(p));
   6:         context.Commit();
   7:     }
   8: }
And then put in your Unit Test Assembly the following method:

   1: [ClassInitialize]
   2: public static void ClassInitialize(TestContext context) {
   3:     DbDatabase.SetInitializer(new DBContextInitializer());
   4: }

If you then use an in memory database it will be fast. The best way to always start from a known state (and to avoid mstest concurrency problems is to put the following code in Your TestInitialize method:
   1: [TestInitialize]
   2: public void TestInitialize()
   3: {
   4:     string key = Guid.NewGuid().ToString();
   5:     TestContext.Properties.Add(DB_NAME_KEY, key);
   6:     repository = new Repository<Product>(key);
   7: }

To delete put the following snippet in your TestCleanUp
   1: [TestCleanup]
   2: public void TestCleanUp()
   3: {
   4:     repository.Dispose();
   5:     DbDatabase.Delete(TestContext.Properties[DB_NAME_KEY].ToString);
   6: }