0

我正在尝试为使用 Dapper 方法的存储库创建一些单元测试,但我无法弄清楚如何让我的代码接受模拟的 DbConnection。我发现 DapperWrapper承认了这个问题并完成了我需要的大部分工作,但是它提供的 IDbExecutor 接口不包括我在代码中打开和关闭连接所需的一些基本 IDbConnection 方法。

例如,下面是我的基本存储库类中的一个属性,它定义了所有存储库中使用的数据库连接,从工厂检索它,如果连接已关闭或尚不存在,则打开连接。此代码不起作用,因为 IDbExecutor 没有公开 Open 或 Close 方法,接口上也不能有 State 属性。

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;
    }
}

有没有办法扩展或继承 IDbExecutor,以便我可以为 SQL 连接(以及在我的模拟连接对象中)引用这些方法和属性?还是有更好的方法来解决整个问题?

编辑

下面是我正在尝试运行的测试示例。我创建了一个实现 IDbExecutor 的 TestExecutor 类。在这种情况下,它被设置为返回我们想要的测试值——我们稍后可能会根据我们的测试需要使用工厂来创建它。

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

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

    //verify that expected deal data was returned
}

DealRepository 基于 AbstractRepository 类,该类包含上面显示的 DB 属性。

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

然后在 DealRepository 本身中,我们针对 DB 对象运行查询:

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

当调用该 Db 属性时,它会运行上面我的原始摘录中的 get 代码,以确保对象存在并且处于打开状态,如果不存在则创建并打开它。这就是我们遇到问题的地方——因为 IDbExecutor 上不存在 Open 和 State 成员。

4

1 回答 1

0

看看DataAbstractions.Dapper

“围绕 Dapper 和 Dapper.Contrib 的轻量级抽象,也维护了 IDbConnection 行为。”

于 2018-10-14T03:22:41.860 回答