我會說這是一部分的你真的想驗證與單元測試,這可以歸結爲你的單元測試的理念是什麼的問題。
我們所做的是我們不必驗證從類型A(測試下)傳遞的linq to entities表達式參數在調用存儲庫協作者(不在測試中)的GetFoo()時使用特定的表達式樹。對於單元測試,我們滿足於驗證GetFoo()方法是否正確調用了正確的簽名。
在你的情況下,它看起來像你正在使用MOQ(?),在這種情況下,將成爲這樣的事情(注意語法亂七八糟的)
_mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce();
對我們來說,這是有道理的,因爲一)嘲笑方法參數表達式樹比較驗證確實是一種痛苦,b)即使我們可以驗證該參數,B實際上將如何解釋參數值的不同組合也會發生變化(如同合約A-> B的語義),如果是這種情況,會使測試變得脆弱。
我們使用自動化故事測試來測試生產A和生產B之間的交互。我們認爲這是測試這些場景的更好方法,因爲它們通常類似於'根據表達式X過濾存儲器A中的所有A並給我所有匹配的對象「。對我們來說,這是有道理的,因爲集成測試(通常有一兩個快樂案例足夠)。
如果這還不夠,我會閱讀a)如何創建自定義Moq匹配器,儘管我不能肯定地說有一個簡單的解決方案(可能很好)或者b)設置期望回調,以便您可以捕獲參數並在測試後對其進行檢查。類似這樣的:
Expression<Func<Entity, bool>> actualExpression = null;
_mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce().Callback((Expression<Func<Entity, bool>> expr => { actualExpression = expr});
// exercise production code
Assert.IsTrue(actualExpression ...... someithing clever here);
注意:以上所有代碼都是在堆棧溢出編輯器中編寫的。不要讓我負責,如果它不編譯,Moq文檔覆蓋此
不知道我明白...而不是將表達式傳遞給安裝方法。如果將其緩存在本地變量中並將其傳遞給設置方法會怎麼樣。 – Gishu 2009-09-10 12:36:54
如果你這樣做,那麼同樣的問題仍然存在!我如何比較兩個表達式是相同的? – 2009-09-13 10:09:38