開始嘗試寫單元測試兩週了,雖然過程中遇到各種困難,但有寫測試的好處真的很有感,每次重構或修改功能時都可以馬上知道是否改壞。

而其中一個困難,就是要如何測試private方法。

使用internal

封裝是在物件導向中非常重要的概念之一,為的就是避免內部重要資料被任意存取,因此絕大多數的變數或方法都會宣告成private,然而這樣卻非常不易做單元測試。

一開始我想說可以直接在測試中反射出private方法直接測試就好,不過看到網路上的大神都說這樣不好,比較推薦的做法是將private修改成internal,讓該方法訪問權限從同個class變成同個Assembly,這樣做的好處就是可以在維持封裝性的同時,也能方便測試。

AssemblyInfo.cs

不過一般情況下,我們的測試跟正常的Code會分開放在兩個不同的Assembly中,這樣還是沒辦法測試到。

因此我們可以在要被測試的方法所在的Assembly下,創建一個名稱為AssemblyInfo.cs的C#檔,並加入以下Code

1
2
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("你的測試Assembly名稱")]

像是我這裡的測試Assembly,就叫做Tests,如此一來,我們的測試專案就可以測試internal的方法囉!

參考資料

【C#】小知識 #9 : 解決私有內部類別單元測試問題:使用 internal + AssemblyInfo.cs 與 protected+繼承,另外補充負面教材:反射Invoke方式。

InternalsVisibleTo in Unity

C# Internal的跨dll访问

__END__