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

xUnit注入ServiceProvider实现缓存依赖注入时遇错误求助

在xUnit中注入ServiceProvider实现缓存依赖注入及错误解决

错误原因

你遇到的ServiceProviderServiceExtensions.GetRequiredService may not be used in setup / verification expressions错误,本质是Moq不允许在Setup或Verify的表达式逻辑里执行实际的服务解析操作。Setup/Verify是用来定义模拟行为、验证调用匹配规则的,不是执行真实服务获取的地方。

正确实现步骤

1. 搭建测试用的依赖注入容器

先通过ServiceCollection注册缓存服务(比如IMemoryCache)和其他业务依赖,再构建ServiceProvider。

2. 提前解析所需服务,避免在Moq表达式中调用GetRequiredService

在测试类构造函数或测试方法开头,先从容器中取出缓存实例或其他服务,再用于测试逻辑或Moq配置。

代码示例

基础缓存测试示例

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Caching.Memory;
using Xunit;

public class CacheDependencyTests
{
    private readonly IMemoryCache _cache;
    private readonly IServiceProvider _serviceProvider;

    public CacheDependencyTests()
    {
        // 构建服务容器
        var services = new ServiceCollection();
        // 注册内存缓存
        services.AddMemoryCache();
        // 注册你的业务服务(如果需要)
        services.AddScoped<IMyCachedService, MyCachedService>();

        _serviceProvider = services.BuildServiceProvider();
        // 提前解析缓存实例,供测试使用
        _cache = _serviceProvider.GetRequiredService<IMemoryCache>();
    }

    [Fact]
    public void Cache_SetAndGet_ReturnsCorrectValue()
    {
        // 直接使用已解析的缓存实例
        _cache.Set("test_key", "test_value");
        var retrievedValue = _cache.Get<string>("test_key");

        Assert.Equal("test_value", retrievedValue);
    }

    [Fact]
    public void BusinessService_UsesCache_Correctly()
    {
        // 解析依赖缓存的业务服务
        var cachedService = _serviceProvider.GetRequiredService<IMyCachedService>();
        var result = cachedService.GetCachedData();

        Assert.NotNull(result);
    }
}

// 示例业务服务
public interface IMyCachedService
{
    string GetCachedData();
}

public class MyCachedService : IMyCachedService
{
    private readonly IMemoryCache _cache;

    public MyCachedService(IMemoryCache cache)
    {
        _cache = cache;
    }

    public string GetCachedData()
    {
        return _cache.GetOrCreate("data_key", entry =>
        {
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
            return "cached_data";
        });
    }
}

修复Moq相关错误的示例

错误写法(触发报错)

// 错误:在Setup表达式中调用GetRequiredService
mockService.Setup(s => s.DoSomething(_serviceProvider.GetRequiredService<IMemoryCache>()))
           .Returns(true);

正确写法

// 先解析缓存实例,再传入Setup表达式
var cache = _serviceProvider.GetRequiredService<IMemoryCache>();
mockService.Setup(s => s.DoSomething(cache))
           .Returns(true);

关键注意点

  • 永远不要在Moq的Setup/Verify表达式中执行GetRequiredService这类实际方法调用,这些表达式只能包含成员调用、参数匹配逻辑。
  • 测试类的依赖解析尽量放在构造函数中,确保每个测试方法都能拿到干净的服务实例(如果需要隔离,也可以在每个测试方法中重新构建容器)。

内容的提问来源于stack exchange,提问作者Dev-lop-er

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:41:05