Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking Enterprise Lib 5 'Database'

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.

like image 285
holsee Avatar asked Aug 18 '10 10:08

holsee


1 Answers

FWIW, I was able to mock a SqlDatabase using Moq. SqlDatabase has a SqlClientPermission attribute which does not play well with Castle Windsor (used by Moq). I had to explicitly instruct Castle to ignore the SqlClientPermission attribute to get the test to work (see line 1 in the example below). Below is a sample unit test (borrowing Steven H's example).

    [TestMethod]
    public void FooRepo_CallsCorrectSPOnDatabase()
    {
        Castle.DynamicProxy.Generators.AttributesToAvoidReplicating.Add(typeof(System.Data.SqlClient.SqlClientPermissionAttribute));
        var mockSqlDb = new Mock<SqlDatabase>("fake connection string");
        mockSqlDb.Setup(s => s.GetStoredProcCommand("sp_GetFoosById"));
        var sut = new FooRepository(mockSqlDb);
        sut.LoadFoosById(1);
        mockSqlDb.Verify(s => s.GetStoredProcCommand("sp_GetFoosById"), Times.Once(), "Stored Procedure sp_GetFoosById was not invoked.");
    }
like image 94
Ganga Avatar answered Sep 22 '22 12:09

Ganga