2017-07-14 4 views
1

J'ai un appel que je souhaite vérifier. Cet appel est à une méthode qui prend une expression Linq comme un argument. Cette expression teste un identifiant d'objet par rapport à l'identifiant d'une variable locale où l'expression est déclarée. Comment puis-je simuler un appel facile à ce déclencheur uniquement lorsque les expressions Linq sont égales (avec la variable locale substituée en) ou si cela n'est pas possible lorsque la variable locale utilisée dans l'expression linq est égale à une certaine valeur.Comment attendre un appel prenant une expression linq spécifique comme argument

Mon code actuel ressemble à ce

A.CallTo(() => SomeMethod.FindBy(item=> item.ItemId == 3)).MustHaveHappened(Repeated.Exactly.Once); 

Comme l'appel et ce dans le code testé.

SomeMethod.FindBy(item=> item.ItemId == id) 

où id est une variable locale. Cela ne fonctionne pas car id n'est pas substitué lorsque l'appel est fait et j'obtiens une erreur comme celle-ci.

SomeInterface`1[[someItem, someItemFolder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].FindBy(item=> (item.ItemId == 3)) 
    Expected to find it exactly once but found it #0 times among the calls: 
    1: SomeInterface`1[UKHO.WeeklyRecipes.EFModels.EFModels.EfTag].FindBy(predicate: tag => (tag.TagId == value(UKHO.WeeklyRecipes.BusinessLayer.PreferenceQueries+<>c__DisplayClass2_0).id)) 

Répondre

3

Vous voyez ce comportement parce FakeItEasy ne peut pas dire si les deux expressions sont les mêmes. Lorsque vous fournissez un objet en tant que contrainte d'argument, FakeItEasy essaie de match the argument value exactly. Dans ce cas, cela signifie appeler la méthode Equals de Expression. Pour citer la documentation:

Lors de la vérification de l'égalité des arguments, FakeItEasy utilise object.Equals. Si le type à vérifier ne fournit pas une méthode adéquate, vous devrez peut-être utiliser la méthode That.Matches décrite dans Custom matching. Faites particulièrement attention aux types dont les méthodes Equals effectuent l'égalité de référence plutôt que l'égalité des valeurs. Dans ce cas, les objets doivent être le même objet afin de correspondre, ce qui produit parfois des résultats inattendus. En cas de doute, vérifiez le comportement Equals du type manuellement.

Donc, essentiellement, cela signifie que si vous avez créé deux variables, l'un contenant l'expression item => item.ItemId == 3 et l'autre item.ItemId == id et les a comparés à l'aide Equals, vous verriez un résultat false, et le fait FakeItEasy. Une approche consisterait à capturer l'expression et ensuite l'interroger pour voir si elle agit comme vous le souhaitez (c'est-à-dire, mais en acceptant 3 et en rejetant les non-3). C'est bizarre, mais comparer les prédicats est difficile. Je parle plus à ce sujet dans une réponse pour How to test for a Match with FakeItEasy on a predicate call?.