16

[當然,問題並不限於特定的「朋友」的實施,隨時雖然指出實現細節,如果相關]使用「朋友」聲明進行單元測試。餿主意?

通過懸而未決的問題閱讀,我偶然發現了InternalsVisibleTo屬性:

指定類型是 僅在 當前組件通常可見的是 另一個組件可見。

C# Programming GuideMSDN具有描述如何使用該屬性,以允許使用的internal方法和類型到另一個組件的截面Friend Assemblies

我想知道是否用它創建一個「隱藏」接口來檢測單元測試程序集使用的庫。它似乎在兩個方向上大量增加耦合(測試代碼在生產組裝中,在測試代碼中關於生產組裝的內部知識),但另一方面它可能有助於創建細粒度測試而不會混淆公共接口。

您在測試時使用朋友聲明有什麼經驗?是你的銀色子彈,還是它開始了死亡之旅?

回答

13

我已經廣泛使用了這種技術 - 這意味着我的單元測試可以測試代碼庫對普通用戶不可見的方面。

雖然使用[InternalsVisibleTo]確實會增加耦合度,但我認爲(小幅)增加值得收穫。我的單元測試已經與測試中的代碼緊密耦合 - 雖然我嘗試通過訪問常規消費者不可見的東西來編寫確保特定結果的測試,而不是特定的實現,但我確實在某種程度上限制了實現。

場地的其他方式中,耦合是最小的 - 在具有上的代碼組件的[InternalsVisibleTo]屬性,並且在標記的一些事情的內部代替私人(或受保護的內部代替保護) 。

(請注意,我這裏忽略了由使用單元測試,這是一個整體的其他討論中引起任何設計變更。)

[InternalsVisibleTo]屬性要求強命名程序集。如果你還沒有這樣做,你可能會覺得這有點麻煩,因爲強命名的程序集可能只依賴於其他強命名的程序集,這可能最終需要修改幾個程序集。

正確獲取屬性可能有點煩瑣,因爲它需要包含測試程序集的公鑰。 IDesign有一個有用的Friend Assembly tool,它在剪貼板上創建屬性,準備粘貼。推薦的。

+0

感謝您提供強有力的命名!我還沒有意識到這一點,但是因爲我認爲我所有的程序集都必須以發佈方式強烈命名,所以我不認爲這是一個真正的問題。 – 2008-11-04 13:13:20

12

這是我曾經親自應用於InternalsVisibleTo的唯一用途 - 它確實非常非常方便。

我不會將單元測試視爲黑盒測試 - 它們已經在某種程度上與實現耦合了。能夠測試內部類型和方法允許更加緊密的焦點(更小的單位)。

3

我認爲使用InternalsVisibleToAttribute來啓用單元測試是非常合理的。我在「單元測試」中的「單元」是一個類,其中包括internal類,所以我想測試它們。 I don't want to unit test private methods,但。

我不認爲爲測試創建一個特殊的專用接口是個好主意。單元測試的價值之一在於,它讓你有機會從該類的消費者的角度思考與你的類的接口;提供後門可以帶來好處。

但是,我的首選是將我的單元測試放在與我的生產代碼相同的部件中。它通常不會影響我的客戶,但它確實爲我簡化了事情,所以我這樣做。當我這樣做時,它會使InternalsVisibleTo問題消失。

3

事實上,單元測試是只有使用,我已經能夠使自己使用InternalsVisibleToAttribute。有了這個,你可以將大部分'私有'方法作爲內部實現,而不是將它們暴露給單元測試框架,以便對類內部不變量進行更有侵入性的測試。

我用這種技術取得了巨大的成功。如果沒有其他的東西,它可以幫助您通過讓您在其他情況下無法訪問的情況下調用私有方法來實現神祕的100%代碼覆蓋目標。

2

我認爲當您使用獨立的程序集將舊版C++代碼與新C#代碼結合在一起時,會出現另一個合法用例。我們已經採用了C++程序集,將它們轉換爲C++/CLI,然後在C#中實現更新的代碼。當我們這樣做時,我們仍然會使用「internal」作爲C#中不真正公開的類/方法,然後將這些作爲朋友程序集提供給舊代碼。