【问题标题】:.NET Core 3.1 IMemoryCache is empty when seeded from integration tests从集成测试中播种时,.NET Core 3.1 IMemoryCache 为空
【发布时间】:2020-09-22 08:50:12
【问题描述】:

由于复杂的搜索,问题是关于使用Entity Framework Core 3.1IMemoryCache 的Web API。示例存储库:

public class UserRepository : IUserRepository
{
    private readonly IMemoryCache _cache;
    private readonly ApplicationDbContext _dbContext;

    public UserRepository(IMemoryCache cache, ApplicationDbContext dbContext)
    {
        _cache = cache;
        _dbContext = dbContext;
    }

    public async Task<List<UserCacheModel>> GetAll()
    {
        List<User> users = _cache.Get<List<User>>("users");
        if (users != null)
        {
            return UserMapper.MapToCacheModelList(users);
        }
        return await _dbContext.Users.ToListAsync();
    }

    public async Task<int> Insert(User user)
    {
        // Add to database
        _dbContext.Users.Add(user);
        await _dbContext.SaveChangesAsync();

        // Add to cache
        List<UserCacheModel> cachedUsers = _cache.Get<List<UserCacheModel>>("users");
        cachedUsers.Add(UserMapper.MapToCacheModel(user));
        }
    }

这是一个非常简单的示例,但它让您清楚地了解它是如何使用的。为了进行复杂的测试,测试项目中有一个自定义的 Web 应用程序工厂,它使用Startup.cs 配置 webhost、DI 和所有内容。显然,DbContext 已从 DI 中移除,并切换到带有EF Core 3.1In-Memory DB

问题是我想在此自定义 Web 应用程序工厂中播种应用程序内 Memory Cache。它工作正常,但是当测试尝试插入用户时,它会失败,因为 List&lt;UserCacheModel&gt; cachedUsers = _cache.Get&lt;List&lt;UserCacheModel&gt;&gt;("users"); 此行将为空。从 Web 应用程序工厂播种的 MemoryCache 似乎与来自 DI 的 UserRepository 中解析的实例不同。

但是,如果我从工厂范围手动解析 IMemoryCache,我可以看到启动时播种的数据。 DbContext 播种正确,除此之外一切正常

更新:

通过创建WebApplicationFactory 的自定义实现,通过Microsoft.AspNetCore.Mvc.Testing 命名空间运行集成测试。这将创建一个 Web 应用程序,就像您调试自己的 API 时一样,因此当您使用将保存用户的请求调用 ActionMethod 时,IMemoryCache 是该新创建的 Web 应用程序的应用内缓存就像一个 docker 容器,与您从集成测试代码中解析的容器不同。

好吧,至少我现在是这么想的。

您知道什么是获得应用内cache 的最佳方法,而无需在您的应用中创建假控制器(仅用于测试目的)?

【问题讨论】:

    标签: c# unit-testing asp.net-core .net-core memorycache


    【解决方案1】:

    考虑在创建 WebApplicationFactory 后设置缓存,如下所示:

    var factory = new MyWebApplicationFactory<Startup>();
    var queriesClient = factory.CreateClient();
    using var scope = factory.Services.CreateScope();
    var memCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
    memCache.Set("Key", Value);
    
    using HttpResponseMessage response = await queriesClient.GetAsync(new Uri(requestUri));
    

    这将直接在工厂范围内设置缓存,现在将使用它。

    【讨论】:

      猜你喜欢
      • 2020-08-18
      • 2020-06-15
      • 2019-09-12
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 2021-07-05
      • 2020-12-10
      • 2022-12-21
      相关资源
      最近更新 更多