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

如何让fallback服务提供者返回编译时未知类型参数的Moq实例

解决方案

你遇到的问题核心是需要根据运行时拿到的Type类型动态创建对应Mock实例,不能直接使用编译期的泛型语法new Mock<serviceType>(),通过反射构造泛型Mock类型即可实现需求。

完整修改后的MockServiceProvider代码

public class MockServiceProvider : IServiceProvider
{
    private readonly Dictionary<Type, object> _services = new();

    public void RegisterServices(params object[] serviceInstances)
    {
        _services.Clear();

        foreach (var serviceInstance in serviceInstances)
        {
            if (serviceInstance is Mock mock)
            {
                var serviceType = mock.GetType().GetGenericArguments().First();
                _services.TryAdd(serviceType, mock.Object);
            }
            else
            {
                _services.TryAdd(serviceInstance.GetType(), serviceInstance);
            }
        }
    }

    public object GetService(Type serviceType)
    {
        if (_services.TryGetValue(serviceType, out var service))
        {
            return service;
        }

        // 动态构造对应类型的Mock实例
        var mockGenericType = typeof(Mock<>).MakeGenericType(serviceType);
        // 传入MockBehavior.Loose保证未设置的成员不会抛异常,符合测试默认需求
        var mockInstance = (Mock)Activator.CreateInstance(mockGenericType, MockBehavior.Loose)!;
        
        // 将生成的Mock实例缓存,保证同一服务类型每次请求都返回同一个实例
        _services.Add(serviceType, mockInstance.Object);
        return mockInstance.Object;
    }
}

逻辑说明

  1. 利用typeof(Mock<>)拿到Mock的开放泛型类型,再通过MakeGenericType方法结合运行时的serviceType构造出闭合的泛型Mock类型
  2. 用Activator.CreateInstance实例化构造好的泛型Mock类型,传入MockBehavior.Loose参数保证默认Mock不会因为调用未设置的成员抛出异常
  3. 生成的Mock对象会存入缓存字典,后续同一服务类型的请求会返回同一个实例,方便你后续需要的时候验证Mock的调用情况

修改后你不需要为每个组件的所有依赖手动注册Mock,只需要注册你需要自定义返回逻辑、验证调用的Mock即可,其余依赖会自动生成默认Mock实例,不会再抛出缺少服务的错误。


内容的提问来源于stack exchange,提问作者Ben Rubin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:45:04