Dapper单元测试怎么写 Dapper仓储层单元测试方法

14次阅读

Dapper仓储层单元测试核心是验证sql逻辑、参数绑定、映射行为及异常路径,需隔离数据库依赖,用内存数据或FakeDbConnection模拟,重点覆盖空集合、NULL参数、列名映射、复杂类型填充等易错点,不测连接与事务。

Dapper单元测试怎么写 Dapper仓储层单元测试方法

写 Dapper 仓储层的单元测试,核心不是去测 Dapper 本身(它已稳定),而是验证你的 SQL 逻辑、参数绑定、映射行为和异常路径是否符合预期。关键在于隔离数据库依赖,用内存数据或模拟对象替代真实数据库连接。

用内存集合 + QueryMultiple 模拟多结果集

Dapper 的 QueryMultiple 常用于一次查多个表(如主从关系)。真实数据库难 mock,但你可以用 SqlMapper.GridReader 的模拟实现,或更简单:把测试数据预先放在 List 中,手动构造类似 QueryMultiple 的返回结构。

  • 定义测试用的内存数据(如 new List { new Order { Id = 1 } }
  • new GridReaderMock(list1, list2) 包装(可自建轻量 mock 类,只需实现 Read()ReadFirst()
  • 在仓储方法中,对 IDbConnection接口抽象(如 IConnectionFactory),测试时注入返回 mock reader 的实现

用 FakeDbConnection 替代真实连接

不依赖 EF 或第三方 mock 工具,可手写一个 FakeDbConnection:它不连数据库,只记录执行的 SQL 和参数,并按预设规则返回测试数据。

  • 继承 DbConnection,重写 CreateCommand() 返回 FakeDbCommand
  • FakeDbCommandExecuteReader() 不查库,而是根据 SQL 字符串匹配预设响应(如 sql.Contains("select * FROM Users") → 返回 new DataTable().AddRow(new User { Name = "Test" })
  • 仓储类接收 IDbConnectionIConnectionFactory,测试时传入 fake 实例

重点测边界与异常,而非“能查出来”

避免写一“查一条用户返回不为空”的测试。真正要覆盖的是容易出错的环节:

  • 空集合查询(Query("") 是否返回空 list 而非 null)
  • 参数为 null 时 SQL 是否报错(如 WHERE Id = @id,传入 id = null,Dapper 默认转成 WHERE Id = NULL —— 这是常见陷阱,应改用 IS NULL
  • 字段名与实体属性名不一致时,[column("user_name")] 是否生效
  • 复杂类型映射(如 User.Profile 是子对象)是否正确填充

不测连接字符串和事务控制逻辑

连接打开/关闭、BeginTransactionCommit 这些属于基础设施代码,不应放在仓储实现里。仓储方法应只专注 SQL 和映射;连接和事务由上层(如服务层或 UnitOfWork)管理。单元测试中也不必验证“是否调用了 Open()”,那属于集成测试范畴。

基本上就这些。不复杂但容易忽略——关键是把仓储当成纯数据搬运工来测,而不是把它和数据库绑死。

text=ZqhQzanResources