gpt4 book ai didi

c# - 使用最小起订量抛出异常模拟 IMemoryCache

转载 作者:可可西里 更新时间:2023-11-01 03:14:17 26 4
gpt4 key购买 nike

我正在尝试模拟 IMemoryCache最小起订量。我收到此错误:

An exception of type 'System.NotSupportedException' occurred in Moq.dll but was not handled in user code

Additional information: Expression references a method that does not belong to the mocked object: x => x.Get<String>(It.IsAny<String>())

我的模拟代码:

namespace Iag.Services.SupplierApiTests.Mocks
{
public static class MockMemoryCacheService
{
public static IMemoryCache GetMemoryCache()
{
Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>();
mockMemoryCache.Setup(x => x.Get<string>(It.IsAny<string>())).Returns("");<---------- **ERROR**
return mockMemoryCache.Object;
}
}
}

为什么会出现该错误?

这是被测代码:

var cachedResponse = _memoryCache.Get<String>(url);

在哪里_memoryCache类型为 IMemoryCache

我如何模拟 _memoryCache.Get<String>(url)让它返回 null?

编辑:如果不是_memoryCache.Set<String>(url, response);,我会如何做同样的事情? ?我不介意它返回什么,我只需要将方法添加到模拟中,这样它就不会在调用时抛出。

按照我尝试过的这个问题的答案:

mockMemoryCache
.Setup(m => m.CreateEntry(It.IsAny<object>())).Returns(null as ICacheEntry);

因为在 memoryCache 扩展中它显示它使用 CreateEntry里面Set .但它因“对象引用未设置到对象的实例”而出错。

最佳答案

根据 MemoryCacheExtensions.cs 的源代码,

Get<TItem>扩展方法使用以下内容

public static TItem Get<TItem>(this IMemoryCache cache, object key) {
TItem value;
cache.TryGetValue<TItem>(key, out value);
return value;
}

public static bool TryGetValue<TItem>(this IMemoryCache cache, object key, out TItem value) {
object result;
if (cache.TryGetValue(key, out result)) {
value = (TItem)result;
return true;
}

value = default(TItem);
return false;
}

请注意,本质上它使用的是 TryGetValue(Object, out Object) 方法。

鉴于用 Moq 模拟扩展方法是不可行的,尝试模拟扩展方法访问的接口(interface)成员。

引用Moq's quickstart更新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);
}

关于c# - 使用最小起订量抛出异常模拟 IMemoryCache,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42381018/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com