【问题标题】:Moq and Async fun using LazyCache使用 LazyCache 的最小起订量和异步乐趣
【发布时间】:2016-12-06 22:33:16
【问题描述】:

我正在尝试模拟一个名为 GetOrAddAsync 的函数。定义为:

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();
                    });

但是,这会返回一个错误:

无法将 lambda 表达式转换为类型“IEnumerable”,因为它不是委托类型。

我的头脑已经准备好用这个语法爆炸了:)

【问题讨论】:

    标签: c# unit-testing moq


    【解决方案1】:

    与其自己使用 Moq 模拟 LazyCache API,为什么不直接使用框架提供的模拟版本?它只执行要缓存的委托,从不执行任何缓存。查看MockCachingService.cs

    【讨论】:

    • 如果你真的想测试缓存是否正常工作,这没什么用
    • @johnstaveley 确实如此,但在这种情况下,您也可以只使用真正的内存缓存,因为它快速可靠。
    【解决方案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();
                    });
    

    【讨论】:

      【解决方案3】:

      除了实际模拟缓存调用之外,我还会通过为被测服务提供CachingService 实例来保留缓存功能。

      信用:Codidact

      【讨论】:

        猜你喜欢
        • 2016-08-24
        • 2016-11-07
        • 1970-01-01
        • 1970-01-01
        • 2018-04-23
        • 1970-01-01
        • 1970-01-01
        • 2014-07-02
        • 2011-12-25
        相关资源
        最近更新 更多