问题描述
问题在于,由于搜索复杂,因此使用Entity Framework Core 3.1
和IMemoryCache
的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中删除,并通过In-Memory DB
切换到EF Core 3.1
。
问题是我想在此自定义Web应用程序工厂中植入应用内Memory Cache
。它工作正常,但是当测试尝试插入用户时,它失败,因为
List<UserCacheModel> cachedUsers = _cache.Get<List<UserCacheModel>>("users");
此行将为空。从Web应用程序工厂中植入的MemoryCache
似乎与从DI中的UserRepository
中解析的实例不同。
但是,如果我从工厂范围手动解析IMemoryCache
,则可以看到启动时播种的数据。 DbContext
已正确播种,除此以外一切正常
更新:
通过创建Microsoft.AspNetCore.Mvc.Testing
的自定义实现,通过WebApplicationFactory
命名空间运行集成测试。这将创建一个Web应用程序,就像您调试自己的API
时一样,因此,当您调用带有保存用户的请求的ActionMethod
时,IMemoryCache
是应用程序内缓存该新创建的Web应用程序就像一个docker容器,与您从集成测试代码中解析的应用程序不同。
至少我现在是这样想的。
有什么想法是最好的方法来获得应用内cache
而不在应用中创建仅用于测试目的的假控制器?
解决方法
考虑在创建 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));
这将直接在工厂范围内设置缓存,现在就可以使用了。