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

C#中Mock返回匿名类型的泛型Repository方法遇问题求助

问题分析与解决

你的问题核心是泛型方法的类型参数不匹配:

  • 实际调用Get方法时,传入的是结构为{DateTime TimeStamp, double? Value}的匿名类型作为TResult,此时泛型方法的类型参数是这个专属的匿名类型。
  • 但你在Setup里把TResult硬编码成了object,并用Func<Model, object>匹配参数,Moq无法将实际的Func<Model, 匿名类型>与该Setup匹配,加上开启了MockBehavior.Strict,因此抛出未匹配到Setup的异常。

正确的Mock写法

需要用泛型Setup匹配任意TResult类型的调用,而非固定为object。修改后的代码如下:

var mock = new Mock<IModel>(MockBehavior.Strict);
// 用泛型Setup匹配所有TResult类型的Get方法调用
mock.Setup<TResult>(repo => repo.Get(
        It.IsAny<IEnumerable<int>>(), 
        It.IsAny<Func<Model, TResult>>()))
    .Returns((IEnumerable<int> ids, Func<Model, TResult> getValues) =>
    {
        // 构造模拟的Model实例
        var mockModel = new Model
        {
            TimeStamp = DateTime.Parse("2022-12-12T16:00:00"),
            Value = 3_000_000
        };
        // 用传入的委托将Model转换为调用方需要的TResult类型(含匿名类型)
        return new[] { getValues(mockModel) } as IReadOnlyCollection<TResult>;
    });

关键说明

  1. 用Setup<TResult>显式声明泛型Setup,让Moq兼容所有TResult类型的Get方法调用。
  2. 在Returns逻辑中直接使用传入的getValues委托,将模拟的Model实例转换为调用方预期的TResult类型,确保返回类型完全匹配,避免类型转换问题。
  3. 无需提前定义_mockValue,通过构造真实Model实例再转换的方式,更贴合原方法的业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:57:27