2017-07-14 56 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?的答案中多談這個問題。

相關問題