c# - 如何在集成测试之间刷新 IAppCache
问题描述
我在 ASP.NET 中使用 xUnit 运行集成测试,其中之一确保多次查询数据只会导致对服务器的 1 次查询。如果我单独运行此测试,那么它可以工作。如果我运行所有测试,则该测试会查询服务器 0 次而不是 1 次。这表明由于其他测试,结果已经在缓存中。
如何确保 IAppCache 在测试开始时为空?我正在使用 LazyCache 实现。
我的猜测是为每个测试重新创建类实例,但静态数据是共享的;并且缓存是静态的。我在缓存上看不到任何“刷新”方法。
解决方案
正如我在我的 OP 评论中提到的 LazyCache afaik 没有明确的操作或任何本机来核对缓存。但是,我认为您可以使用一些选项。
- 使用 Remove 在每次测试之前/之后实现一个方法以删除缓存条目;
- 为不在测试之间保留缓存的测试提供不同的 LazyCache 缓存提供程序
- 深入 LazyCache,获取底层缓存提供程序,看看是否有任何方法可以清除缓存条目
1或3将是我的选择。从测试的角度来看,1 意味着您需要了解所测试内容的内部结构。如果是我,我会有点懒,可能会写几行代码来清除缓存。
默认情况下,LazyCache 使用MemoryCache作为缓存提供程序。MemoryCache 也没有明确的清除操作,但是当紧凑百分比设置为 1.0 时, Compact看起来基本上可以清除缓存。要访问它,您需要从 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 小时。
推荐阅读
- android - 使用 Android/Kotlin QR Scanner App 和最新版本的 Google ML Kit Scan Barcode 崩溃
- mysql - 如何在querydsl中使用rownum
- excel - Excel VBA循环多列以查找是否满足条件
- c - 分解条件以减少 DRAM 使用
- c# - Google 课堂/教育 API 从学生到课程(和教师)再到作业
- ios - @Binding var a: Int 和 Binding 的区别
在 SwiftUI 中? - android - Android Studio API 19:谷歌地方未找到 api 异常 15
- python - 如何在python中将数据表数据框拆分为训练和测试数据集
- c - 为什么我在 sys/stat.h 库中得到“未定义的对 `_stat` 的引用”?
- elasticsearch - 使用关键字词进行 Elasticsearch KNN 搜索