views:

80

answers:

2

Is it possible to mock the enterprise library 5 version of 'Database'? If so... how?

There is no IDatabase interface (which is a mystery as I though Microsoft P&P would be more on the ball about testability benefits of exposing such an interface).

I have a Repository class which used EntLib 5 Data Access Application Block.

I am retro fitting unit tests into this class and need to mock out the dependency on the Database object. This class is now passed the Database via its constructor and uses a Database object to perform operations on the Db.

I use the following to resolve an instance of the Database to be passed to my Repository:

Container.RegisterType<IFooRepository, FooRepository>(
    new InjectionConstructor(
        EnterpriseLibraryContainer.Current.GetInstance<Database>("FooDbConnStr")
    )
);

I don't wish these unit tests to become integration tests.

I have tried using Moq to create a dynamic mock of the Database type, but this has proved tricky as Database requires a connection string and a DbProviderFactory in its constructor. Maybe if there was such a thing as a MockDbProviderFactory.

This is the form that the unit test is taking:

EntLib UnitTest Attempt to Mock Database

Aside: I also find the use of a static logger class very difficult to test. Hopefully I am missing some trick here, but I must say I am disappointed with testability thus far.

A: 

I used FakeItEasy http://code.google.com/p/fakeiteasy/.

I created a mock of SqlDatabase (inherits from Database with a friendlier constructor) passed it to the FooRepostory, called the function under test and asserted expected calls that were made to the Database.

[Test]
public void FooRepo_CallsCorrectSPOnDatabase()
{
    var mockDb = A.Fake<SqlDatabase>(x => x.WithArgumentsForConstructor(new object[] { "fakeconnStr" }));
    var sut = new FooRepository(mockDb);
    sut.LoadFoosById(1);
    A.CallTo(() => mockDb.GetStoredProcCommand(Db.SProcs.GetFoosById)).MustHaveHappened(Repeated.Once);
}
StevenH
A: 

Database is an abstract base class, and DbProviderFactory is also abstract, so you can mock them both out. As long as you mock out the operations that you're calling on the Database type (just about everything there is virtual so you should be ok there) you don't actually need to do anything in the provider factory. And the connection string can just be empty or null or whatever.

Chris Tavares