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

来源:这里教程网 时间:2026-02-21 17:36:23 作者:

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

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

Dapper 的

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

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

用 FakeDbConnection 替代真实连接

不依赖 EF 或第三方 mock 工具,可手写一个

FakeDbConnection
:它不连数据库,只记录执行的 SQL 和参数,并按预设规则返回测试数据。

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

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

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

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

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

连接打开/关闭、

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

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

相关推荐

热文推荐