根据
MemoryCacheExtensions.cs 的源代码,
Get<TItem>
扩展方法使用以下内容。
public static object Get(this IMemoryCache cache, object key)
{
cache.TryGetValue(key, out object value);
return value;
}
public static TItem Get<TItem>(this IMemoryCache cache, object key)
{
return (TItem)(cache.Get(key) ?? default(TItem));
}
public static bool TryGetValue<TItem>(this IMemoryCache cache, object key, out TItem value)
{
if (cache.TryGetValue(key, out object result))
{
if (result is TItem item)
{
value = item;
return true;
}
}
value = default;
return false;
}
请注意,本质上它是使用 TryGetValue(Object, out Object)
方法。
考虑到使用 Moq 无法模拟扩展方法,请尝试模拟扩展方法访问的接口成员。
参考 Moq 的快速入门 更新 MockMemoryCacheService
,以便为测试正确设置 TryGetValue
方法。
public static class MockMemoryCacheService {
public static IMemoryCache GetMemoryCache(object expectedValue) {
var mockMemoryCache = new Mock<IMemoryCache>();
mockMemoryCache
.Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue))
.Returns(true);
return mockMemoryCache.Object;
}
}
来自评论
Note that when mocking TryGetValue
(in lieu of Get), the out
parameter
must be declared as an object
even if it isn't.
For example:
int expectedNumber = 1
object expectedValue = expectedNumber.
If you don't do this then it will match a templated extension method of the
same name.
这里是一个使用修改后的服务来模拟 memoryCache.Get<String>(url)
并使其返回 null
的示例
[TestMethod]
public void _IMemoryCacheTestWithMoq() {
var url = "fakeURL";
object expected = null;
var memoryCache = MockMemoryCacheService.GetMemoryCache(expected);
var cachedResponse = memoryCache.Get<string>(url);
Assert.IsNull(cachedResponse);
Assert.AreEqual(expected, cachedResponse);
}
更新
同样的过程也可以应用于Set<>
扩展方法,它看起来像这样。
public static TItem Set<TItem>(this IMemoryCache cache, object key, TItem value) {
var entry = cache.CreateEntry(key);
entry.Value = value;
entry.Dispose();
return value;
}
这种方法利用了CreateEntry
方法,该方法返回一个ICacheEntry
,也会受到影响。因此,设置模拟以返回一个模拟的条目,就像以下示例中一样。
[TestMethod]
public void _IMemoryCache_Set_With_Moq() {
var url = "fakeURL";
var response = "json string";
var memoryCache = Mock.Of<IMemoryCache>();
var cachEntry = Mock.Of<ICacheEntry>();
var mockMemoryCache = Mock.Get(memoryCache);
mockMemoryCache
.Setup(m => m.CreateEntry(It.IsAny<object>()))
.Returns(cachEntry);
var cachedResponse = memoryCache.Set<string>(url, response);
Assert.IsNotNull(cachedResponse);
Assert.AreEqual(response, cachedResponse);
}
out
关键字? - Nkosi