2011-03-24 60 views
1

晚上好,我該如何構建這個類,以便儘可能多地進行單元測試?

我正在努力讓我的腦袋圍繞單元測試,並且我在確定在進行集成測試之前可以推進單元測試的程度有點麻煩。

我正在從事的項目的一個示例:它有一個使用DirectorySearcher對Active Directory執行LDAP搜索並將結果作爲Person對象返回的類。我的第一個想法是爲DirectorySearcher獲取界面,然後創建一個相當複雜的存根,我可以用它來測試。但是,這被證明是有問題的,因爲DirectorySearcher似乎沒有使用接口,並且需要大量代碼才能成功保存。

我的下一個想法是創建一個Searcher類,它在內部使用DirectorySearcher,它可以讓我測試LDAP結果和Person對象映射之間的映射,但這並沒有太大的幫助,而且還是另一個級別抽象。

所以,我想底線是這樣的:有沒有一種方法的結構,所以我可以做大部分的單元測試工作?我寧願讓集成測試套件儘可能小,因爲我必須對不斷變化的外部數據源進行測試。我懷疑有這樣做的模式,但我一直無法找到它。

謝謝!

+4

計算機科學中的所有問題都可以通過另一個層次的間接方法來解決:P(我知道這沒有什麼幫助,但是你的問題中的一個句子讓我想起了這句話)。 – 2011-03-24 21:27:17

+0

@Martin ...「除了間接層太多的問題」(謝謝大衛惠勒) – 2011-03-24 21:30:17

回答

5

如果你有一個你不能依賴注入的類,那麼最好的模式是創建一個包裝對象幷包裝該對象。然後,你可以注入你的包裝器(或包裝器的模擬)來獲得這個功能。

所以在你的情況下,你創建一個內部調用DirectorySearcher的包裝器「Searcher」類是正確的。無論您需要調用DirectorySearcher的任何方法,您都可以在Searcher類上提供虛擬方法。然後你可以創建一個帶有重寫方法的模擬搜索類,並在單元測試時注入(或者,讓Moq爲你創建它)

+0

謝謝,我明白這一點。我與大多數人苦苦掙扎的一件事情是,何時創建一個接縫和單元測試,而不是僅僅投入毛巾並進行集成測試。你有什麼粗糙的指導方針,你會建議? – Jacob 2011-03-25 19:07:16

+0

基本上,當你有一些跨越你的應用程序邊界的操作時,如果它不能被注入,我通常會包裝它。 AKA,文件IO,網絡調用,操作系統級別的東西。如果你打電話給你沒有寫的東西,那麼包裝imo通常是一個好主意。 – Tejs 2011-03-25 19:34:51

0

你應該爲Searcher創建自己的接口,而不是你的Searcher對象在實現它的類中,這樣你就可以依賴注入你的存根或模擬。

1

從我所能理解的情況來看,你的班級(爲了討論起見,我們將其命名爲「PeoplePerson」)需要根據特定標準來抓取/接觸到人員。所以它可以安全地說你的類需要一個PeopleRepository。我們將擔心PeopleRepository如何能夠在稍後爲「GetPeople(標準)」服務。現在,如果您試駕PeoplePerson的開發,您很快就會發現正確的界面成員(他們通常傾向於技術/ impl。不可知論者)。使用模擬框架(我假設LDAP將使你的單元測試更慢)以注入模擬成PeoplePerson

公共PeoplePerson(IPeopleRepository 庫){... //緩存它}

現在弄清楚IPeopleRepository上的每個方法是如何實現的。爲PeopleRepository編寫測試,該測試針對包裝已知數據集的真正的ActiveServer/LDAP提供程序。這些測試將會很慢(集成測試與ActiveServer集成測試),但它們讓所有人免於擔心LDAP/ActiveServer。

我發現創建這個抽象是一個很好的投資。

相關問題