如何使用 It.IsAny AddItemFactory 函数模拟 IAppCache 的 GetOrAddAsync 方法
How to mock IAppCache's GetOrAddAsync method with It.IsAny AddItemFactory function
我正在测试的方法中有这段代码:
var devices = await _cache.GetOrAddAsync(_cacheKey, AddItemFactory, DateTimeOffset.Now.AddMinutes(Configuration.DeviceInMinutes));`
其中 _cache
是 IAppCache
并且在测试中被 new Mock<IAppCache>();
模拟
AddItemFactory 具有以下签名:
private async Task<IDictionary<int, Device>> AddItemFactory()
在我的测试中我写了:
_appCache.Setup(x => x.GetOrAddAsync(
It.IsAny<string>(),
It.IsAny<Func<Task<IDictionary<int, Device>>>>(),
It.IsAny<DateTimeOffset>())
).ReturnsAsync(fakeDictionary);
评估 .Setup 时,我的测试崩溃并出现以下错误:
System.NotSupportedException : Invalid setup on an extension method: x => x.GetOrAddAsync<IDictionary<int, Device>>(It.IsAny<string>(), It.IsAny<Func<Task<IDictionary<int, Device>>>>(), It.IsAny<DateTimeOffset>())
我认为它被正确地嘲笑了,因为 Visual Studio intellisense 没有抱怨并且签名是错误的,但我不明白发生了什么。
GetOrAddAsync 方法重载是一个扩展方法;不能模拟扩展方法。
GetOrAddAsync<T>(
this IAppCache cache,
string key,
Func<Task<T>> addItemFactory,
DateTimeOffset expires)
您需要在IAppCache
接口上模拟以下方法:
Task<T> GetOrAddAsync<T>(string key, Func<ICacheEntry, Task<T>> addItemFactory);
如果您想使用 Moq 来执行此操作,库 LazyCache.Testing.Moq(免责声明 - 我是作者)通过以下设置实现此操作:
cachingServiceMock.Setup(m => m.GetOrAddAsync(
It.IsAny<string>(),
It.IsAny<Func<ICacheEntry, Task<T>>>()))
.Returns(Task.FromResult(cacheEntryValue));
其中 cacheEntryValue
是调用应该 return 的任务结果值。
如果您不需要使用 Moq,假设您使用的是 GetOrAdd* 方法,您应该能够使用 LazyCache 库提供的内置伪造 (MockCachingService
) doco.
我正在测试的方法中有这段代码:
var devices = await _cache.GetOrAddAsync(_cacheKey, AddItemFactory, DateTimeOffset.Now.AddMinutes(Configuration.DeviceInMinutes));`
其中 _cache
是 IAppCache
并且在测试中被 new Mock<IAppCache>();
模拟
AddItemFactory 具有以下签名:
private async Task<IDictionary<int, Device>> AddItemFactory()
在我的测试中我写了:
_appCache.Setup(x => x.GetOrAddAsync(
It.IsAny<string>(),
It.IsAny<Func<Task<IDictionary<int, Device>>>>(),
It.IsAny<DateTimeOffset>())
).ReturnsAsync(fakeDictionary);
评估 .Setup 时,我的测试崩溃并出现以下错误:
System.NotSupportedException : Invalid setup on an extension method: x => x.GetOrAddAsync<IDictionary<int, Device>>(It.IsAny<string>(), It.IsAny<Func<Task<IDictionary<int, Device>>>>(), It.IsAny<DateTimeOffset>())
我认为它被正确地嘲笑了,因为 Visual Studio intellisense 没有抱怨并且签名是错误的,但我不明白发生了什么。
GetOrAddAsync 方法重载是一个扩展方法;不能模拟扩展方法。
GetOrAddAsync<T>(
this IAppCache cache,
string key,
Func<Task<T>> addItemFactory,
DateTimeOffset expires)
您需要在IAppCache
接口上模拟以下方法:
Task<T> GetOrAddAsync<T>(string key, Func<ICacheEntry, Task<T>> addItemFactory);
如果您想使用 Moq 来执行此操作,库 LazyCache.Testing.Moq(免责声明 - 我是作者)通过以下设置实现此操作:
cachingServiceMock.Setup(m => m.GetOrAddAsync(
It.IsAny<string>(),
It.IsAny<Func<ICacheEntry, Task<T>>>()))
.Returns(Task.FromResult(cacheEntryValue));
其中 cacheEntryValue
是调用应该 return 的任务结果值。
如果您不需要使用 Moq,假设您使用的是 GetOrAdd* 方法,您应该能够使用 LazyCache 库提供的内置伪造 (MockCachingService
) doco.