Estoy tratando de burlarme del método de un repositorio así
public async Task<WhitelistItem> GetByTypeValue(WhitelistType type, string value)usando Moq ReturnsAsync, así:
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(); });pero recibo este error en la línea "... ReturnsAsync((Tipo de lista blanca...):
No se puede convertir la expresión lambda para escribir 'Modelo. WhitelistItem' porque no es un tipo de delegado
WhitelistType es un Enum como ese:
public enum WhitelistType { UserName, PostalCode }Busqué por horas y no encontré ninguna respuesta a mi problema.
¿Alguna pista?
Puede usar ReturnsAsync con lambdas, exactamente como en el ejemplo de código de la pregunta. Ya no es necesario usar Task.FromResult() . Solo necesita especificar los tipos de argumentos de delegado lambda. De lo contrario obtendrá el mismo mensaje de error:
No se puede convertir la expresión lambda para escribir 'Modelo. WhitelistItem' porque no es un tipo de delegado
Para dar un ejemplo, lo siguiente funciona con la última versión de 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(); }); Tienes que usar Returns con Task.FromResult :
.Returns((WhitelistType type, string value) => { return Task.FromResult( (from item in whitelist where item.Type == type && item.Value == value select item).FirstOrDefault() ); });Sé que esta es una vieja pregunta, pero la única respuesta dada aquí no funcionó para mí y pude resolverla. Parece que primero debe incluir los tipos de argumento de la función simulada como parámetros de tipo para ReturnsAsync() , seguido del tipo de clase simulada y luego el tipo de devolución.
Por ejemplo: .ReturnsAsync<T1, T2, TMock, TResult>((arg1, arg2) => { ... } )
Donde T1, T2 son los tipos de argumentos de la función simulada y (arg1, arg2) son los argumentos reales dados cuando se llamó a la simulación.
Entonces, dado el código del OP, se vería así:
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(); });Editar: Me di cuenta más adelante en la respuesta anterior de que los tipos se dan en la lambda que funciona. Si omite los tipos, como hice yo, no lo hará. Tendrías que usar el formulario que usé.