2017-07-14 31 views
1

我有一个电话我希望检查已发生。这个调用是一个将Linq表达式作为参数的方法。这个表达式测试了一个对象id和声明表达式的局部变量的id。我怎样才能让一个假的简单的调用,只有当Linq表达式相等时(用局部变量替换)或者当linq表达式中使用的局部变量等于某个值时触发才是可能的。如何等待以特定linq表达式作为参数的呼叫

我当前的代码看起来像这样

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

由于调用,这在代码中进行测试。

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

其中id是局部变量。这不起作用,因为在进行调用时id不会被替换,并且我得到这样的错误。

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)) 

回答

3

您看到了这种行为,因为FakeItEasy无法判断这两个表达式是否相同。当您提供一个对象作为参数约束时,FakeItEasy会尝试match the argument value exactly。在这种情况下,这意味着调用ExpressionEquals方法。引述文件:

当参数平等检查,FakeItEasy使用object.Equals。如果要检查的类型未提供足够的方法,则可能必须使用Custom matching中描述的That.Matches方法。特别注意其方法执行引用相等而不是值相等的类型。在这种情况下,对象必须是相同的对象才能匹配,并且这有时会产生意想不到的结果。如有疑问,请手动验证类型的Equals行为。

所以,本质上,这意味着如果你创建了两个变量,一个包含了表达item => item.ItemId == 3和其他item.ItemId == id,并使用Equals他们相比,你会看到一个false结果,也是如此FakeItEasy。

一种方法是捕捉表达式,然后询问它是否按照你喜欢的方式行动(即接受3并拒绝非3s)。这很尴尬,但比较谓词很难。我在How to test for a Match with FakeItEasy on a predicate call?的答案中多谈这个问题。

相关问题