如何Mock带参数的Dapper存储过程调用?
解决Dapper存储过程调用的FakeItEasy Mock问题
先看你实际调用存储过程的代码:
var parameters = new DynamicParameters(); parameters.Add("MYPARAM", field.ListPickListCode, DbType.String, ParameterDirection.Input, int.MaxValue); options = dbConn.QuerySingleOrDefault<string>(sql: "mysp", param: parameters, commandType: CommandType.StoredProcedure);
你之前两种Mock方式失败的原因:
- 第一种只指定了
"mysp"参数,没有匹配实际调用时传入的param和commandType,FakeItEasy找不到对应匹配项,返回默认值(null)。 - 第二种虽然传了完整参数,但
DynamicParameters是引用类型,FakeItEasy默认检查引用是否完全相等,你测试代码里创建的实例和业务代码里的不是同一个,所以匹配失败。
下面是两种可行的Mock方案:
方案1:忽略无关参数,匹配关键条件
如果不需要验证参数具体内容,只需匹配存储过程名称和调用类型,用A<>忽略其他参数:
IDynamicDatabaseConnection dbConnMock = A.Fake<IDynamicDatabaseConnection>(); // 匹配存储过程名称、任意DynamicParameters实例、指定CommandType A.CallTo(() => dbConnMock.QuerySingleOrDefault<string>( "mysp", A<DynamicParameters>._, A<IDbTransaction>._, A<int?>._, CommandType.StoredProcedure )).Returns("someValue");
A<DynamicParameters>._表示接受任意DynamicParameters实例,A<IDbTransaction>._和A<int?>._对应你调用时省略的transaction和commandTimeout参数(默认值为null)。
方案2:验证参数具体内容
如果需要确保传入的参数值正确,用A<>.That.Matches()检查DynamicParameters内的参数值:
IDynamicDatabaseConnection dbConnMock = A.Fake<IDynamicDatabaseConnection>(); var expectedParamValue = fieldDefinition.ListPickListCode; // 预期的参数值 A.CallTo(() => dbConnMock.QuerySingleOrDefault<string>( "mysp", A<DynamicParameters>.That.Matches(p => p.Get<string>("MYPARAM") == expectedParamValue ), A<IDbTransaction>._, A<int?>._, CommandType.StoredProcedure )).Returns("someValue");
通过p.Get<string>("MYPARAM")取出参数值与预期值对比,只要内容匹配就会触发Mock返回。
注意:要确保IDynamicDatabaseConnection接口中QuerySingleOrDefault的参数顺序和接口定义一致,避免因参数顺序错误导致匹配失败。
内容的提问来源于stack exchange,提问作者tRuEsAtM
相关产品推荐
相关产品推荐

