【问题标题】:Moq ReturnsAsync() with parameters带参数的起订量 ReturnsAsync()
【发布时间】:2015-10-10 05:15:17
【问题描述】:

我正在尝试像这样模拟存储库的方法

public async Task<WhitelistItem> GetByTypeValue(WhitelistType type, string value)

使用 Moq ReturnsAsync,如下所示:

static List<WhitelistItem> whitelist = new List<WhitelistItem>();

var whitelistRepositoryMock = new Mock<IWhitelistRepository>();

whitelistRepositoryMock.Setup(w => w.GetByTypeValue(It.IsAny<WhitelistType>(), It.IsAny<string>()))
                                    .ReturnsAsync((WhitelistType type, string value) =>
                                    {
                                        return (from  item in whitelist
                                                where item.Type == type && item.Value == value
                                                select item).FirstOrDefault();
                                    });

但我在“... ReturnsAsync((WhitelistType type...):

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

WhitelistType 就是这样的枚举:

public enum WhitelistType
    {
        UserName,
        PostalCode
    }

我按小时搜索,但没有找到任何问题的答案。

有什么线索吗?

【问题讨论】:

    标签: c# unit-testing moq


    【解决方案1】:

    Moq v4.5.28 开始

    您可以将 ReturnsAsync 与 lambdas 一起使用,就像问题的代码示例中一样。不再需要使用Task.FromResult()。您只需需要指定 lambda 委托参数的类型。否则你会得到同样的错误信息:

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

    举个例子,以下内容适用于最新版本的起订量:

    whitelistRepositoryMock.Setup(w => w.GetByTypeValue(It.IsAny<WhitelistType>(), It.IsAny<string>()))
                                    .ReturnsAsync((WhitelistType type, string value) =>
                                    {
                                        return (from  item in whitelist
                                                where item.Type == type && item.Value == value
                                                select item).FirstOrDefault();
                                    });
    

    Moq v4.5.28 之前(答案由Alexei Levenkov 提供)

    您必须将ReturnsTask.FromResult 一起使用:

    .Returns((WhitelistType type, string value) =>
     {
         return Task.FromResult(
           (from  item in whitelist
               where item.Type == type && item.Value == value
               select item).FirstOrDefault()
           );
    });
    

    【讨论】:

    • 这对你有用吗?我得到“无法将 lambda 表达式转换为类型 x,因为它不是委托类型”,即使在指定类型并完全像您一样执行之后也是如此。最新最小起订量 4.14 或其他东西
    【解决方案2】:

    我知道这是一个老问题,但这里给出的一个答案对我不起作用,我能够弄清楚。似乎您必须将模拟函数的参数类型作为类型参数包含到ReturnsAsync() 首先,然后是模拟类类型,然后是返回类型。

    例如:.ReturnsAsync&lt;T1, T2, TMock, TResult&gt;((arg1, arg2) =&gt; { ... } )

    T1, T2 是模拟函数参数的类型,(arg1, arg2) 是调用模拟函数时给出的实际参数。

    所以给定 OP 的代码,它看起来像这样:

    whitelistRepositoryMock.Setup(w => w.GetByTypeValue(It.IsAny<WhitelistType>(), It.IsAny<string>()))
                           .ReturnsAsync<WhitelistType, string, IWhiteListRepository, WhitelistItem>((type, value) =>
                           {
                                return (from  item in whitelist
                                        where item.Type == type && item.Value == value
                                        select item).FirstOrDefault();
                           });
    

    编辑:我在前面的答案中稍后意识到,类型是在 lambda 中给出的,它确实有效。如果您像我一样省略类型,则不会。你必须使用我使用的表格。

    【讨论】:

      猜你喜欢
      • 2015-02-02
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 2013-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多