【问题标题】:Asp.Net Core: reset memoryCache for Integration TestsAsp.Net Core:为集成测试重置 memoryCache
【发布时间】:2021-07-26 14:23:33
【问题描述】:

我创建了一些基本的集成测试来调用我的 Api 并查看权限是否正常工作。现在我遇到了一个问题,即运行更多的所有测试其中一个失败 - 如果单独运行,它不会。

原因是,一旦用户登录,我就使用 IMemoryCache 来存储某些权限。但是对于我的集成测试,权限存储在缓存中,当我尝试更改它们以进行测试时,它们不会刷新.

一般来说,有没有办法让每个集成测试的 MemoryCache 失效?

我的一个集成测试类基本上是这样做的:

    public IntegrationTest(CustomWebApplicationFactory<Namespace.Startup> factory)
    {
        _factory = factory;
        _client = _factory.CreateClient();

       // init the DB here etc... 

       var response = await _client.GetAsync("api/Some/Path");

       Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }

有没有办法告诉工厂不要使用缓存或使用模拟缓存或类似的东西?

编辑:

缓存在我的 startup.cs 中设置如下:

public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();
        
        [...]
    }
    
}

这通过 DependenyInjection 注入到我的控制器中,如下所示:

private IMemoryCache _cache;
private MemoryCacheEntryOptions _cacheOptions;
const int CACHE_LIFETIME_IN_DAYS = 7;

public SomeController(IMemoryCache cache) {
    _cache = cache;
    _cacheOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromDays(CACHE_LIFETIME_IN_DAYS));
}

我在我的控制器中使用它与_cache.TryGetValue_cache.Set

【问题讨论】:

  • 你能说明一下缓存是在哪里以及如何设置和使用的吗?
  • 好的,我编辑了最初的问题,其中包含有关如何设置缓存的信息。谢谢!

标签: c# .net-core integration-testing


【解决方案1】:

作为一种快速修复,您可以尝试执行以下操作:

var memoryCache = _factory.Services.GetService<IMemoryCache>() as MemoryCache;
memoryCache.Compact(1.0);

当您需要重置缓存时。

但我建议要么考虑在测试之间不共享 _factory(尽管它可能会影响性能),要么将 done in the docs 覆盖(就像它是带有上下文的 done in the docsIMemoryCache 到您可以在外部控制的东西你需要。

UPD

由于默认情况下测试不会并行运行,因此您可以手动注册MemoryCache 的实例。像这样的:

public class CustomWebApplicationFactory<TStartup>
    : WebApplicationFactory<TStartup> where TStartup : class
{
    internal readonly MemoryCache MemoryCache;
    public CustomWebApplicationFactory()
    {
        MemoryCache = new MemoryCache(new MemoryCacheOptions());
    }
    public void ClearCache() => MemoryCache.Compact(1.0);
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            var descriptor = services.SingleOrDefault(
                d => d.ServiceType ==
                     typeof(IMemoryCache));
            services.Remove(descriptor);
            services.AddSingleton<IMemoryCache>(MemoryCache);
        });
    }
}

在测试电话factory.ClearCache():

public void Test1()
{
    var factory = new CustomWebApplicationFactory<Startup>();
    var memoryCache = factory.Services.GetService<IMemoryCache>() as MemoryCache;
    memoryCache.Set("test", "test");
    factory.ClearCache();
    Assert.IsFalse(memoryCache.TryGetValue("test", out var val));
}

如果您需要使用同一个工厂并行运行测试(尽管我会说最好创建不同的工厂),那么您可以创建IMemoryCache 实现,它将以某种方式确定(例如在客户端请求中传递一些特定的标头)不同的测试运行并为它们返回不同的MemoryCache 实例。

【讨论】:

  • 那么您将如何覆盖文档中的 memoryCache 呢?我试过了,但我看不到这样做的方法
  • @Chi 我想说,在大多数情况下,只需注册手动创建的 MemoryCache 实例即可。
  • @Chi 很乐意提供帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 1970-01-01
  • 2019-09-12
  • 2018-05-24
  • 1970-01-01
相关资源
最近更新 更多