- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我知道 IMemoryCache.Set 是一个扩展方法,所以它不能被模拟。人们已经为这种情况提供了解决方法,例如 NKosi here 的解决方法。 .我想知道如何为我的 MemoryCache 返回一个值的数据访问层实现这一点,当找不到它时,它从数据库获取数据,将其设置为 MemoryCache 并返回所需的值。
public string GetMessage(int code)
{
if(myMemoryCache.Get("Key") != null)
{
var messages= myMemoryCache.Get<IEnumerable<MyModel>>("Key");
return messages.Where(x => x.Code == code).FirstOrDefault().Message;
}
using (var connection = dbFactory.CreateConnection())
{
var cacheOptions = new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromHours(1) };
const string sql = @"SELECT Code, Message FROM MyTable";
var keyPairValueData = connection.Query<KeyPairValueData>(sql);
myMemoryCache.Set("Key", keyPairValueData, cacheOptions );
return keyPairValueData.Where(x => x.Code == code).FirstOrDefault().Message;
}
}
以下是我的单元测试 - 当然它不起作用,因为我无法模拟 IMemoryCache
[Fact]
public void GetMessage_ReturnsString()
{
//Arrange
// Inserting some data here to the InMemoryDB
var memoryCacheMock = new Mock<IMemoryCache>();
//Act
var result = new DataService(dbConnectionFactoryMock.Object, memoryCacheMock.Object).GetMessage(1000);
//assert xunit
Assert.Equal("Some message", result);
}
最佳答案
我要说的第一件事是为什么不使用真正的内存缓存?它会更好地验证行为并且不需要模拟它:
// Arrange
var memCache = new MemoryCache("name", new NameValueCollection());
//Act
var result = new DataService(dbConnectionFactoryMock.Object, memCache).GetMessage(1000);
// Assert: has been added to cache
memCache.TryGetValue("Key", out var result2);
Assert.Equal("Some message", result2);
// Assert: value is returned
Assert.Equal("Some message", result);
如果你真的想模拟它,这里有一个关于如何做到这一点的指南:
因为它是一个扩展方法,所以你需要确保它可以被原样调用。在您的情况下,扩展方法将调用模拟。由于您没有提供预期的行为,因此它可能会失败。
您需要查看扩展方法的代码,检查它访问的内容,然后确保您的模拟符合预期行为。该代码可在此处获得: https://github.com/aspnet/Caching/blob/master/src/Microsoft.Extensions.Caching.Abstractions/MemoryCacheExtensions.cs#L77
这是代码:
public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value, MemoryCacheEntryOptions options)
{
using (var entry = cache.CreateEntry(key))
{
if (options != null)
{
entry.SetOptions(options);
}
entry.Value = value;
}
return value;
}
因此,从那里,您可以看到它访问 CreateEnty
并期望从中获得一个对象。然后它调用 SetOptions
并在条目上分配 Value
。
你可以这样模拟它:
var entryMock = new Mock<ICacheEntry>();
memoryCacheMock.Setup(m => m.CreateEntry(It.IsAny<object>())
.Returns(entryMock.Object);
// maybe not needed
entryMock.Setup(e => e.SetOptions(It.IsAny<MemoryCacheEntryOptions>())
...
执行此操作时,将在模拟上调用扩展方法并返回模拟条目。您可以修改实现并使其执行任何您想要的操作。
关于c# - XUnit 如何模拟 IMemoryCache ASP.NET Core,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53223316/
我有一个 CacheService使用 GetOrCreateAsync基于键创建缓存。我正在缓存一个照片实体,它有一个 byte[]属性(property)。 这可以很好地缓存并按预期检索。但是,如
我正在尝试将我的 .Net 框架应用程序迁移到 .Net Core,在此过程中,我想将我的内存缓存从 System.Runtime.Caching/MemoryCache至Microsoft.Exte
我创建了一个全新的 ASP.NET Core Web API 项目。这是 Startup.cs 中的 ConfigureServices: public void ConfigureServi
我对 ASP.Net Core、C#、OOP、Javascript ……基本上是我目前使用的所有内容的新手。过去几个月我一直在阅读和学习以开始一个新的开发项目。总而言之,我正在稳步前进,但我遇到了 I
我正在使用 asp net core 1.0 和 xunit。 我正在尝试为一些使用 IMemoryCache 的代码编写单元测试。但是,每当我尝试在 IMemoryCache 中设置一个值时,我都会
我正在尝试模拟 IMemoryCache最小起订量。我收到此错误: An exception of type 'System.NotSupportedException' occurred in Mo
我目前正在执行以下操作以将列表存储在 IMemoryCache 中: _memoryCache.Set("PriceList", horsepricelist); 并访问它/返回数据: public
我正在创建一个 .net core 3.1 Worker Service 应用程序。我有一个使用 IMemoryCache 接口(interface)进行依赖注入(inject)的类。我有以下类的构造
我正在使用 IMemoryCache缓存从身份服务器检索到的 token 。 过去我用过 GetOrCreateAsync Microsoft.Extensions.Caching.Abstracti
我有一个从 Visual Studio 2015 Community Edition 创建的 ASP.NET Web 应用程序。 .NET Framework 是 4.6.1。 我不知道我的 Web
我一直在使用类似于示例 1 的操作来为我的 .NET Core API 异步缓存 json 结果。 MemoryCache 是 IMemoryCache 的实例。 示例 1(按预期工作): [Http
我正在尝试使用 Microsoft.Extensions.Caching.Memory.IMemoryCache 接口(interface)/类。 我需要向缓存中添加一个新项目,并确保我不会覆盖任何其
我有一个带有 API 的 ASP.NET Core MVC 项目。 然后我在名为 Infrastructure. 的同一个解决方案中有一个类库。 我的 API 在类库基础结构中调用存储库方法,在类 U
我们正在使用 .NET Core 3.1 和 Microsoft.Extensions.Caching.Memory.IMemoryCache (v3.1.24) 及其实现 Microsoft.Ext
.Net Core 为两个接口(interface)( MemoryCache 和 DistributedMemoryCache )提供内存实现,但假设我们有一个可用的 IDistributedCac
我知道 IMemoryCache.Set 是一个扩展方法,所以它不能被模拟。人们已经为这种情况提供了解决方法,例如 NKosi here 的解决方法。 .我想知道如何为我的 MemoryCache 返
我正在寻找一种方法来包装为某些数据调用远程 WCF 服务的服务。例如,这样的服务可能看起来像这样 public interface IAsyncSvc { Task GetData(int k
我正在编写一个简单的测试用例来测试我的 Controller 在调用我的服务之前调用缓存。我正在使用 xUnit 和 Moq 来完成这项任务。 我遇到了一个问题,因为 GetOrCreateAsync
我向 IMemoryCache 添加一个值 _cache.Set("Key", "Value", DateTimeOffset.UtcNow); 我想通过其他方法获取这个key的绝对过期值。 或者 我
我正在使用 IMemoryCache 将数据存储在缓存中...但它会不断向 SQL Server 发送 sql 调用,即使在缓存存在的情况下执行不会运行该代码。 我的查找服务 public class
我是一名优秀的程序员,十分优秀!