Moq возвращает Async() с параметрами
Я пытаюсь издеваться над способом хранилища
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...):
Невозможно преобразовать лямбда-выражение в тип "Model.WhitelistItem", поскольку оно не является типом делегата.
WhitelistType - это Enum, подобный этому:
public enum WhitelistType
{
UserName,
PostalCode
}
Я искал по часам и не нашел ответа на мою проблему.
Есть какие-нибудь подсказки?
2 ответа
ReturnsAsync
не имеет лямбда-версию в отличие Returns
один.
Исправить: использовать Returns
с Task.FromResult
.Returns((WhitelistType type, string value) =>
{
return Task.FromResult(
(from item in whitelist
where item.Type == type && item.Value == value
select item).FirstOrDefault()
);
});
Принятый ответ устарел. Теперь вы можете использовать ReturnsAsync
с лямбдами, точно так же, как в примере кода вопроса. Не нужно использовать Task.FromResult()
больше Вам просто нужно указать типы аргументов лямбда-делегата. В противном случае вы получите то же сообщение об ошибке:
Невозможно преобразовать лямбда-выражение в тип "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();
});
Я знаю, что это старый вопрос, но один ответ, данный здесь, не сработал для меня, и я смог его понять. Кажется, вам нужно включить типы аргументов имитируемой функции в качестве параметров типа для
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();
});
Изменить: позже в предыдущем ответе я понял, что типы указаны в лямбде, которая действительно работает. Если вы не укажете типы, как это сделал я, этого не произойдет. Вам нужно будет использовать форму, которую использовал я.