You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#单元测试Mock Dapper Query方法失败:spResponse计数为0如何解决?

解决FakeItEasy Mock Dapper Query存储过程返回空集合的问题

常见问题原因

  • 方法重载匹配失败:Dapper的Query有多个重载,Mock时若未匹配到业务代码实际调用的重载(比如遗漏CommandType.StoredProcedure参数、参数数量/类型不匹配),FakeItEasy会返回默认空集合。
  • 泛型类型未指定:Query是泛型方法,Mock时必须明确指定业务代码中使用的实体泛型类型,否则Mock的是无关重载。
  • 参数匹配策略错误:若使用精确参数匹配,但业务代码传入的参数值与Mock设定的不一致,也会触发默认空返回。

正确Mock方式

假设业务代码如下:

public class DataService
{
    private readonly IDynamicDatabaseConnection _dbConn;

    public DataService(IDynamicDatabaseConnection dbConn) => _dbConn = dbConn;

    public List<User> GetUsers(int departmentId)
    {
        var param = new { DeptId = departmentId };
        return _dbConn.Query<User>("GetUsersByDept", param, commandType: CommandType.StoredProcedure).ToList();
    }
}

对应的Mock测试代码:

// 1. 创建Mock实例
var mockDb = A.Fake<IDynamicDatabaseConnection>();

// 2. 准备模拟返回数据
var mockUsers = new List<User>
{
    new User { Id = 1, Name = "张三" },
    new User { Id = 2, Name = "李四" }
};

// 3. 精确匹配Query重载及参数
A.CallTo(() => mockDb.Query<User>(
        A<string>.That.Matches(sp => sp == "GetUsersByDept"),
        A<object>.Ignored, // 忽略匿名参数,若需精确匹配可改用((dynamic)obj).DeptId == 1
        A<IDbTransaction>.Ignored,
        A<int?>.Ignored,
        A<CommandType?>.That.Matches(ct => ct == CommandType.StoredProcedure)))
    .Returns(mockUsers.AsQueryable());

// 4. 注入Mock并执行测试
var service = new DataService(mockDb);
var result = service.GetUsers(1);
Assert.AreEqual(2, result.Count);

关键注意事项

  • 必须确保Mock的Query重载参数与业务代码完全对齐,包括是否传入transaction、commandTimeout等可选参数。
  • 针对匿名参数,优先用A<object>.Ignored匹配;若需精确校验参数值,可通过dynamic类型解析匿名对象属性。

内容的提问来源于stack exchange,提问作者tRuEsAtM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:02:40