2016-12-06 2 views
1

Я пытаюсь высмеять функцию с именем GetOrAddAsync. Он определяется как:Moq и Async fun с помощью LazyCache

Task<T> GetOrAddAsync<T>(string key, Func<Task<T>> addItemFactory, DateTimeOffset expires); 

Когда я использую его в моем фактическом коде я использую это нравится:

DateTimeOffset cacheTimeout = new DateTimeOffset(DateTime.Now.AddHours(config.CacheHours)); 
Func<Task<IEnumerable<int>>> func = async() => await (from s in dbContext.Names select s.First).ToListAsync(); 

return await cache.GetOrAddAsync(key, func, cacheTimeout); 

Так в основном, если ключ существует, то он будет возвращать то, что в нем, и если не она будет создавать ключ и заполнить его данными, возвращаемыми из переданного в Func <>.

Моя насмешливый попытка этого до сих пор выглядит следующим образом:

cache.Setup(x => x.GetOrAddAsync(It.IsAny<string>(), It.IsAny<Func<Task<IEnumerable<int>>>>(), It.IsAny<DateTimeOffset>())) 
       .ReturnsAsync(async (string key, Func<Task<IEnumerable<int>>> func, DateTimeOffset policy) => 
        { 
         return await func.Invoke(); 
        }); 

Однако это возвращает ошибку:

Невозможно преобразовать лямбда-выражения к типу «IEnumerable», потому что это не тип делегата ,

Мой ум готов взорваться с этим синтаксисом :)

ответ

2

ReturnsAsync не будет использоваться, когда у вас есть функция обратного вызова асинхронной, думать о нем, как делать .ReturnsAsync(foo) просто сокращение для .Returns(Task.FromResult(foo)). Так что вы пытаетесь сделать, это то же самое, как

cache.Setup(x => x.GetOrAddAsync(It.IsAny<string>(), It.IsAny<Func<Task<IEnumerable<int>>>>(), It.IsAny<DateTimeOffset>())) 
       .Returns(Task.FromResult(async (string key, Func<Task<IEnumerable<int>>> func, DateTimeOffset policy) => 
        { 
         return await func.Invoke(); 
        })); 

Переключаю используя обычный Returns( и ваши функции должны работать нормально.

cache.Setup(x => x.GetOrAddAsync(It.IsAny<string>(), It.IsAny<Func<Task<IEnumerable<int>>>>(), It.IsAny<DateTimeOffset>())) 
      .Returns(async (string key, Func<Task<IEnumerable<int>>> func, DateTimeOffset policy) => 
       { 
        return await func.Invoke(); 
       }); 
+0

Я был так близок :). Спасибо, что сработало! – user441521

0

Вместо того, чтобы дразнить API LazyCache используя MOq себя, почему бы не использовать фиктивную версию, представленную рамки? Он просто выполняет все, что ваш кеш-кеш, и никогда не кэширует. Выезд MockCachingService.cs

Смежные вопросы