TDD with the new Enterprise Library DAAB – level 300

First, I give props to they guys at Microsoft who put out the Enterprise
Library.  I especially like the data access application block.  I do, however,
have one beef with it.  Everyone preaches “code to an interface”, and ADO.NET
exhibits this (IDataReader, IDbCommand, etc), but the DAAB doesn’t do this. 
Consequently, I can’t stub out a mock object to decouple the DAAB from the code
I’m trying to unit test with NUnit.  I then tried NMock to create a dynamic
mock, but the ExecuteReader(string, params object) method wasn’t marked as
virtual.  After changing it to virtual and recompiling the source, NMock would
work (it appears most methods were marked virtual, but that some were
overlooked).  Not having the interface to stub out _really_ makes TDD
difficult.  It forces me to use dynamic mocks (which are more brittle).

Here’s a quick test I whipped up to create a Category class that is a record
in the Categories table of Northwind.  Note the use of NMock to get my unit test
to work without the dependency on the DAAB:

    7 public class Category {
private string
_name = string.Empty;
   10     private
static Database _database = null;
private static
string _databaseInstance = “DEV”;
public string
Name {
   14         get { return this._name; }
   15         set {
this._name = value; }
   16     }
public static
Database Database {
   19         get {
        if(_database == null)
            _database =
        return _database;
   24         }
   25         set {
_database = value; }
   26     }
public Category(int categoryID)
   29     {
   30         IDataReader reader =
Category.Database.ExecuteReader(“GetCategoryByID”, categoryID);
   33             this._name =
   34         }
   35     }
   36 }

Now my test:

   10 [TestFixture]
   11 public class CategoryTest
   12 {
   14     public void
   16         Mock mockDatabase = new NMock.DynamicMock(typeof(Database));
   17         Mock mockReader = new NMock.DynamicMock(typeof(IDataReader));
    mockReader.ExpectAndReturn(“GetString”, “Beverages”, 56);
mockReader.ExpectAndReturn(“GetOrdinal”, 56, “CategoryName”);
   21         mockReader.ExpectAndReturn(“Read”,
mockDatabase.ExpectAndReturn(“ExecuteReader”, mockReader.MockInstance,
“GetCategoryByID”, new object[]{1});
    Category.Database = (Database)mockDatabase.MockInstance;
    Category existing = new
Assert.AreEqual(“Beverages”, existing.Name);
   31     }
   32 }

I had to use NMock for the Database class, so I just used it for the
IDataReader interface as well (as I further this class, I will modify that to
use a mock stub that implements IDataReader).

This code work and allows me to test the instantiation of my Category object
with the ID of a category.

The data access block is awesome, but I WISH I had an interface to code
against instead of just the abstract class.  I guess I’m going to have to insert
the interface myself.

By the way, I attended the webcast about this block this afternoon, and I
have to say that it was the most fun webcast I’ve every attended.  The
presenters were in shorts and cutting up and laughing the whole time.  🙂