Первое, что я бы сказал, почему бы не использовать реальный кэш памяти? Было бы намного лучше проверить поведение, и нет нужды издеваться над ним:
// 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>())
...
Когда вы сделаете это, для макета будет вызван метод расширения, который вернет имитируемую запись. Вы можете изменить реализацию и заставить ее делать что угодно.