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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:06:04