2013-05-28 23 views
3

是否有一個標準的單元測試代碼,其中依賴不實現接口的方法?例如,System.Net.Http名稱空間僅公開具體的類。如果我想單元測試依賴於System.Net.Http中的某個具體類的類,我應該僅僅構造一個例如HttpRequestMessage的實例,設置它的屬性,然後將這個新構造的對象提供給被測系統?子類HttpRequestMessage是否有意義,並讓它實現一個可以被模擬/存根的自定義接口?是否有一個標準的方法來進行單元測試代碼的依賴不實現接口?

+0

當你想在你控制這些依賴的依賴測試。子類化/抽象不一定是必需的。你真正想要做的就是將你的依賴關係存儲起來,並使其符合你的測試對象的期望。 – Polity

回答

8

推薦的做法是將此對象包裝在您創建的類中,該類本身實現了一個接口。然後你可以在你的代碼中使用這個包裝類,然後你可以提供這個包裝的模擬版本來代替真實的類​​。您不會使用此方法對其進行子類化,而是包含它並使用委派(不要與代表混淆!)來轉發每個方法。例如,你可以創建一個HttpRequestMessageWrapper類,該類繼承自IHttpRequestMessage(你定義的,包括HttpRequestMessage的所有公共屬性,儘管你可能只通過實現你使用的屬性來獲得)。

或者,您可以使用支持墊片的測試框架,這是一個基本上爲您實現此封裝的框架,並用墊片版本替換對對象的調用。 Microsoft Fakes(在VS 2012 MS測試中引入)可以做到這一點。

墊片通常用於替換常見的框架調用,如DateTime.Now,因此您可以在測試期間提供特定的值。

+0

謝謝。這是有道理的,並且應該允許我靈活地在將來修改HttpRequestMessageWrapper等內部工作,而不會違反任何合同。 –

+0

@BradfordFisher - 這並不是真的會改變這個類的內部工作,儘管它可以更容易地替換通過接口調用的特定功能。你正在包裝的類將不知道你的包裝。我建議不要改變包裝類的行爲,因爲這可能會導致各種意想不到的問題。 –

0

我建議你看看:AutoFixture http://autofixture.codeplex.com/它可以幫助你以你想要的方式構建對象。在你的例子中,HttpRequestMessage,你可以自定義燈具:fixture.Customize<HttpRequestMessage>(c => {}); 在單元測試中有很多使用AutoFixture的例子。或者你可以在這裏發佈你想測試的代碼,我可以嘗試提供幫助。

+0

Autofixture不會幫助大多數框架類,因爲您必須能夠對功能進行存根。例如,如何使用Autofixture幫助存根Socket類?它只會幫助實質上POCO的課程。 –

+0

完全同意你的意見。所有情況下都沒有銀色小雞。在AutoFixture中,你可以設置你想要使用的模擬框架。我同意你的回答,但我發現自己可以在大多數情況下使用AutoFixture + RhinoMock(或Moq)進行單元測試。至少在我已經完成的項目中。 –

+0

AutoMocking僅適用於Interfaces和抽象類,問題的關鍵在於如何測試使用不實現這些類的具體類的類。 –

0

另一個很好的工具,測試遺留代碼爲Typemock

相關問題