2017-08-14 2 views
0

Pourquoi cela fonctionne-t-il Returns((string food) => eat(food)) alors que ce n'est pas le cas: Returns(food => eat(food))?Pourquoi Moq demande-t-il parfois une déclaration de type explicite dans les retours?

exemple de travail complet:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var animal = new Mock<IAnimal>(); 
     Func<string, string> eat = food => $"Nom nom nom {food}"; 

     // works 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(eat); 

     // works 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food)); 

     //cannot convert lambda expression to type 'string' because it is not a delegate type 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => eat(food)); 

     //cannot convert lambda expression to type 'string' because it is not a delegate type 
     animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => $"Nom nom nom {food}"); 
    } 
} 

public interface IAnimal 
{ 
    string Eat(string food); 
} 
+1

Ce n'est pas Moq qui l'exige, c'est le compilateur C#. Il est probable que le nombre énorme de surcharges de la méthode '.Returns' (18 à mon compte) donne au compilateur trop d'options. Aussi, à l'avenir, lorsque le code ne fonctionne pas (comme dans, ne compile pas), s'il vous plaît envoyer le message d'erreur réel. Dans ce cas, il est "Impossible de convertir l'expression lambda en type 'chaîne' car ce n'est pas un type délégué". –

+0

@ LasseV.Karlsen Pour être juste l'erreur est intégrée dans les commentaires de code, même si je suis d'accord, il devrait être plus évident. – DavidG

+0

@ LasseV.Karlsen Je comprends cela, mais j'ai seulement remarqué ce comportement dans la fonction Moq Returns, et je suis curieux de savoir ce qui déclenche le compilateur en ne trouvant pas la bonne méthode pour appeler. Je m'attends à ce qu'il y ait un conflit avec certaines des autres méthodes de retours, mais lequel? –

Répondre

1

En réponse comme une réponse que je puisse coller un code ...

Ce n'est pas le nombre de Lasse V. comme surcharge Karlsen suggère. Le comportement est dû au casting. Voir les commentaires dans le code ci-dessous:

//works because "eat" knows it's own input type 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(eat); 

// works because you are explicitly typing input param 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food)); 

Cependant, les choses deviennent un peu plus compliqué lorsque vous utilisez une expression lambda, parce que l'expression lambda n'a pas en fait un type d'entrée

animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => eat(food)); 
// is equivalent to: 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns((string food) => {return eat(food); }); 

Mais {return eat(food);} n » Je ne connais pas le type food.

Ainsi, lorsque vous appelez

animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => eat(food)); 
animal.Setup(a => a.Eat(It.IsAny<string>())).Returns(food => $"Nom nom nom {food}"); 

le compilateur ne sait pas ce que la nourriture type est.