Moq Setup带默认参数的泛型方法报Invalid callback错误如何解决?
问题原因分析
- 参数数量不匹配报错的原因:你在Setup阶段匹配的是完整4个参数的
GetJSON方法,但Returns中传入的委托仅接收1个参数。Moq要求Returns的委托参数数量、类型必须和Setup的方法参数完全对应,即使后三个参数你不需要使用,也必须在委托中完成占位。 - 简化写法无法生效的原因:C#的默认参数是编译期语法糖,调用方不传参数时编译器会自动补全默认值传入方法,但Moq的Setup是匹配运行时的方法签名,仅传1个参数的写法相当于匹配只有1个参数的
GetJSON重载,而你的接口中不存在该重载,自然无法匹配成功。
正确配置方案
方案1:匹配所有参数传入场景(无论后三个参数是否传值都命中)
如果不需要用到方法传入的参数,直接用ReturnsAsync简化写法即可:
Mock<IAdFileService> mock = new Mock<IAdFileService>(); mock.Setup(x => x.GetJSON<dynamic>( It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<dynamic>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<dynamic>>() )).ReturnsAsync(ServiceResponse<string>.Create( "Json Data", "http://test.com/", "Json Data", "http://test.com/" ));
如果需要用到传入的参数做逻辑处理,Returns的委托需要补全所有4个参数:
mock.Setup(x => x.GetJSON<dynamic>( It.IsAny<FileRequest>(), It.IsAny<FileItemsSerializer<dynamic>>(), It.IsAny<CsvConfiguration>(), It.IsAny<ClassMap<dynamic>>() )).Returns((FileRequest req, FileItemsSerializer<dynamic> ser, CsvConfiguration config, ClassMap<dynamic> mapper) => { // 可在此处使用传入的参数做自定义逻辑 return Task.FromResult(ServiceResponse<string>.Create( "Json Data", "http://test.com/", "Json Data", "http://test.com/" )); });
方案2:仅匹配只传第一个参数的调用场景
如果被测代码只会调用省略后三个参数的GetJSON,可以在Setup时明确指定后三个参数为默认值null:
mock.Setup(x => x.GetJSON<dynamic>( It.IsAny<FileRequest>(), null, null, null )).ReturnsAsync(ServiceResponse<string>.Create( "Json Data", "http://test.com/", "Json Data", "http://test.com/" ));
注意事项
如果被测代码调用GetJSON时使用的不是dynamic作为泛型参数,而是具体的业务类,需要将Setup中的dynamic替换为对应的具体类,否则泛型参数不匹配会导致Setup命中失败。
内容的提问来源于stack exchange,提问作者user1730289
相关产品推荐
相关产品推荐

