ASP.NET Core:重置内存缓存以进行集成测试

问题描述 投票:0回答:1

我创建了一些基本的集成测试来调用我的 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个回答
1
投票

作为快速解决方案,您可以尝试执行以下操作:

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

当您需要重置缓存时。

但我建议要么考虑在测试之间不共享

_factory
(尽管它可能会对性能产生一些影响),要么覆盖(就像在文档中完成的那样)IMemoryCache
到你可以在外部控制的东西根据您的需要。

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
 的不同实例。

© www.soinside.com 2019 - 2024. All rights reserved.