我在 ASP.NET 中使用 xUnit 运行集成测试,其中之一确保多次查询数据只会导致对服务器的 1 次查询。如果我单独运行此测试,那么它会起作用。如果我运行所有测试,则此测试会查询服务器 0 次而不是 1 次。这表明由于其他测试结果已经在缓存中。
如何确保 IAppCache 在测试开始时为空?我正在使用 LazyCache 实现。
我的猜测是类实例是为每个测试重新创建的,但是静态数据是共享的;并且缓存是静态的。我没有在缓存上看到任何“刷新”方法。
最佳答案
正如我在 OP 评论中提到的,LazyCache afaik 没有明确的操作或任何本地内容来破坏缓存。不过,我认为您有几种选择。
- 在每次测试之前/之后实现一个方法,使用 Remove 删除缓存条目;
- 为不在测试之间保留缓存的测试提供不同的 LazyCache 缓存提供程序
- 深入研究 LazyCache,获取底层缓存提供程序并查看是否有任何方法来清除缓存条目
我会选择 1 或 3 个。从测试的角度来看,1 意味着您需要了解所测试内容的内部结构。如果是我,我有点懒惰,可能会写几行来破坏缓存。
默认情况下,LazyCache 使用 MemoryCache作为缓存提供者。 MemoryCache 也没有明确的清除操作,但 Compact当紧凑百分比设置为 1.0 时,看起来它基本上可以清除缓存。要访问它,您需要从 LazyCache 获取底层 MemoryCache 对象:
IAppCache cache = new CachingService();
var cacheProvider = cache.CacheProvider;
var memoryCache = (MemoryCache)cacheProvider.GetType().GetField("cache", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(cacheProvider);
memoryCache.Compact(1.0);
完整的 LINQPad 工作示例:
void Main()
{
IAppCache cache = new CachingService();
Console.WriteLine(cache.GetOrAdd("Foo", () => Foo.NewFoo, DateTimeOffset.Now.AddHours(1.0)));
var cacheProvider = cache.CacheProvider;
var memoryCache = (MemoryCache)cacheProvider.GetType().GetField("cache", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(cacheProvider);
memoryCache.Compact(1.0);
Console.WriteLine(cache.Get<Foo>("Foo"));
}
public class Foo
{
public static Foo NewFoo
{
get
{
Console.WriteLine("Factory invoked");
return new Foo();
}
}
public override string ToString()
{
return "I am a foo";
}
}
每次运行都会产生以下结果:
如果我删除紧凑调用,我们会得到以下结果:
因此这表明 Compact(1.0) 将核对缓存条目,即使到期日期为 +1 小时。
关于c# - 如何在集成测试之间刷新 IAppCache,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61739103/