【发布时间】:2019-04-12 21:08:39
【问题描述】:
我了解 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);
}
【问题讨论】:
-
由于使用了所有扩展,因此尝试完全模拟该接口很棘手。这就是为什么我开始建议使用链接答案中的实际内存缓存。
-
当前测试有什么问题
-
对象引用未设置为 myMemoryCache.Set("Key", keyPairValueData, cacheOptions ); 处的对象错误实例;
-
您是否尝试过使用链接答案中的方法?
-
创建一个新的 MemoryCache 实例而不是模拟工作非常好,我已经完成了,但不确定是否应该使用实际对象而不是模拟。因此,@Kenneth 的第一个建议非常有效。不过还没有尝试过他的嘲讽建议。
标签: c# unit-testing mocking moq xunit