带参数的 Moq Return nsAsync()

我正在尝试模仿一个仓库的方法

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

使用 Moq Return sAsync,如下所示:

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

但是我在行中得到了这个错误..:

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

WhitelistType 是这样一个 Enum:

public enum WhitelistType
{
UserName,
PostalCode
}

我找了好几个小时,都没有找到问题的答案。

有线索吗?

51570 次浏览

来自 Moq v4.5.28及以上版本

您可以将 ReturnsAsync与 lambdas 一起使用,正如在问题的代码示例中一样。不需要再使用 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();
});

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

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

例如: .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();
});

编辑: 在前面的回答中,我后来意识到类型是在 lambda 中给出的,lambda 确实起作用。如果你像我一样把这些类型排除在外,它就不会。你得用我用过的表格。