How to support additional IDbConnection methods in Dapper (using DapperWrapper)?

.net c# dapper unit-testing

Question

I'm attempting to create some unit tests for a repository that uses Dapper methods, but I'm having trouble figuring out how to get my code to accept a mocked DbConnection. I found that DapperWrapper acknowledges this problem and accomplishes most of what I need, but the IDbExecutor interface it provides does not include some of the base IDbConnection's methods I need in my code to open and close the connection.

For example, below is a property from my base repository class that defines the database connection used in all the repositories, retrieves it from a factory, and Opens the connection if it's closed or doesn't yet exist. This code doesn't work because IDbExecutor does not expose the Open or Close methods, nor can there be a State property on the interface.

private IDbExecutor _db;

protected IDbExecutor Db
{
    get
    {
        if (_db == null)
        {
            _db = DbConnectionFactory.GetConnection();
            _db.Open();
        }
        else if (_db != null && _db.State != ConnectionState.Open)
        {
            _db.Open();
        }
        return _db;
    }

    set
    {
        _db = value;
    }
}

Is there a way to extend or inherit the IDbExecutor in such a way that I can reference these methods and properties for the SQL connection (and in my mock connection object)? Or is there a better approach to this whole problem?

Edit:

Below is an example of a test I'm trying to run. I've created a TestExecutor class that implements IDbExecutor. In this case it's set up to return the test values we want - we'll probably use a factory to create it according to our test needs later.

[Test]
public void TestGetAllDealsSuccess()
{        
    var executor = new TestExecutor();

    var dealRepo = new DealRepository(executor);
    var deals = dealRepo.GetAllDeals();

    //verify that expected deal data was returned
}

The DealRepository is based on an AbstractRepository class that contains the DB property shown above.

protected AbstractBaseRepository(IDbExecutor conn)
{
    _db = conn;
}

Then in the DealRepository itself we run our queries against the DB object:

var results = Db.Query<Deal>("GetDeals", sprocParameters).ToList();

When that Db property is called it runs the get code in my original excerpt above, which ensures the object exists and is open, and if not creates one and opens it. That's where we run into the problem - since the Open and State members don't exist on IDbExecutor.

Popular Answer

Take a look at DataAbstractions.Dapper.

"A light abstraction around Dapper and Dapper.Contrib that also maintains the behavior IDbConnection."




Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why