Moq使用参数返回Async()

Dan*_*ina 40 c# unit-testing moq

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

public async Task<WhitelistItem> GetByTypeValue(WhitelistType type, string value)
Run Code Online (Sandbox Code Playgroud)

使用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();
                                    });
Run Code Online (Sandbox Code Playgroud)

但我在行中收到此错误"... ReturnsAsync((WhitelistType type ...):

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

WhitelistType是这样的枚举:

public enum WhitelistType
    {
        UserName,
        PostalCode
    }
Run Code Online (Sandbox Code Playgroud)

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

有线索吗?

Pau*_*sma 30

接受的答案已过时.您现在可以使用ReturnsAsynclambdas,就像在问题的代码示例中一样.不需要再使用Task.FromResult()了.您只需要指定lambda委托参数的类型.否则,您将收到相同的错误消息:

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

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

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();
                                });
Run Code Online (Sandbox Code Playgroud)

  • 为什么这对你有用?即使在指定类型并按照您的方式进行操作后,我仍收到“无法将 lambda 表达式转换为类型 x,因为它不是委托类型”。最新起订量 4.14 或其他 (2认同)

Cha*_*ski 12

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

例如: .ReturnsAsync<T1, T2, TMock, TResult>((arg1, arg2) => { ... } )

模拟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();
                       });
Run Code Online (Sandbox Code Playgroud)

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