Moq框架Setup配置Callback时抛出参数不匹配异常如何解决
报错原因
这个异常是Moq的参数匹配校验规则导致的:Callback委托的泛型参数列表,必须和你Setup的目标方法的形参列表数量、类型完全一致,哪怕你Setup的时候给某个参数传了固定值(比如这里你给第二个参数传了null),Callback也必须完整声明所有形参的类型。
你当前Setup的StartExecution方法一共2个入参:
- 第一个是
Func<Stream, ImportOperation<T>, bool>类型的处理委托 - 第二个是
string类型的可选参数id
但你写Callback时只声明了第一个Func类型的泛型参数,漏掉了第二个string参数,Moq检测到参数列表不匹配就直接抛出了该异常。
另外你的测试代码还有两个会导致编译/运行失败的隐藏问题:
- Mock的接口类型、方法泛型参数写错:你实例化Mock时用的是
IMyInterface<IImportLine>,但实际给出的接口定义是IImportTransport<T>,且StartExecution的第二个Func入参类型是ImportOperation<T>,不是你写的IMyInterface<IImportLine> - 存在非法实例化接口的写法:
new IMyInterface<IImportLine>()无法编译,接口不能直接实例化,需要传入对应实现类实例或者Mock生成的代理对象。
修复方案
- 补全Callback的泛型参数列表,把第二个string类型的参数加上,和目标方法形参一一对应
- 对齐Mock的接口、方法参数类型,和接口定义保持一致
- 替换非法的接口实例化代码,传入符合类型要求的对象
修复后的参考代码:
// 和给出的接口定义对齐类型为IImportTransport var myMock = new Mock<IImportTransport<IImportLine>>(); myMock.Setup(m => m.StartExecution( It.IsAny<Func<Stream, ImportOperation<IImportLine>, bool>>(), null)) .Callback<Func<Stream, ImportOperation<IImportLine>, bool>, string>( (action, id) => { // 第二个参数传ImportOperation<IImportLine>类型的合法实例,不能直接new接口 // 可根据测试场景传入测试实现类实例或Mock生成的代理对象 var testOperation = new ImportOperation<IImportLine>(); action(null, testOperation); });
如果不需要在Callback里使用第二个id参数,也可以直接用自动匹配写法,不需要显式声明泛型参数:
var myMock = new Mock<IImportTransport<IImportLine>>(); myMock.Setup(m => m.StartExecution( It.IsAny<Func<Stream, ImportOperation<IImportLine>, bool>>(), null)) .Callback((Func<Stream, ImportOperation<IImportLine>, bool> action, string id) => { var testOperation = new ImportOperation<IImportLine>(); action(null, testOperation); });
内容的提问来源于stack exchange,提问作者DevelopmentIsMyPassion
相关产品推荐
相关产品推荐

