2009-10-20 139 views
1

我經常設計系統,我在我的系統中有一個類,有一堆受保護的方法。受保護的方法是因爲它們應該可以被專業化訪問,因此,我認爲受保護的方法是我的一般類和任何專門類之間的契約。模式的名稱是什麼?

因此我想測試這些方法的行爲正確,所以我的單元測試將需要訪問受保護的方法,這東西是不可能在C#中,除非使用骯髒的黑客一樣思考。

的解決方案,我一般選擇的是我創造一個公開這些受保護的方法爲公共我的單元測試中一個專門的類。因爲我始終將單元測試保留在單獨的程序集中,所以系統代碼本身無法訪問這些類,並且在我的系統代碼中,受保護的函數仍然受到保護。

// In the system code assembly 
namespace MySystem { 
    public class SomeClass { 
     protected void DoSomething() { 
      ... 
     } 
    } 
} 

// In the unit test assembly 
namespace MySystem.Unittests { 
    public class SomeClass2 : SomeClass { 
     public new void DoSomething() { 
      base.DoSomething(); 
     } 
    } 
} 

我的單元測試現在能夠通過實例化專業類來測試父類的保護成員的行爲。

我也用這個甚至進一步能夠嘲笑對象和模擬函數調用受保護的虛擬功能,但這些代碼是有點複雜,所以我就砍了這一點。

我覺得完成這個任務是如此直截了當,我不可能是這樣做的唯一的人的這種方式,所以我認爲必須有一個常見的命名慣例?

+0

我只是使用接口,並在測試時保留私有方法。無論如何,如果您遵循SRP,他們就不應該受到很大的影響。 – 2009-10-20 15:09:55

+0

我會將SomeClass2重命名爲TestableSomeClass。這澄清了爲什麼和什麼。 (並且,是的,我們在這裏使用這種模式很多...) – 2009-10-20 15:14:35

+0

@Arjan - 我的問題的一點是找出SomClass2; – Pete 2009-10-20 15:41:28

回答

1

我只是做這個的時候我不控制需要被測試的類。 Charles指出當你控制源代碼時,你可以在.NET中做什麼。

你的情況有點不同,因爲你的類是打算用作超類的,所以通過子類測試它很有意義(因爲這個類並不打算獨立存在)。在這種情況下,你基本上在做一個Test-Specific Subclass的變體。鏈接中描述的模式更重要的是覆蓋行爲,如果您有一個不是先寫測試並且耦合度很高的類,那麼它非常有用,這是一種很好的方式來區分依賴關係(通常作爲中間步驟獲取一個單獨的類作爲參數傳遞)。在你的情況下,「覆蓋」是爲了增加訪問的目的,但似乎符合相同的模式。

+0

其實在閱讀了模式的描述後,我會說測試特定的子類正是我所做的。該模式將「行爲暴露子類」描述爲特定於測試的子類的示例。我沒有意識到該網站,但它看起來很棒,我認爲在那裏我會找到構建更好的測試代碼的靈感,謝謝! (我已經訂購了這本書) – Pete 2009-10-21 06:16:17

1

不知道是不是whaty你正在做一個模式的名字,但.NET有一個解決方案...讓內部保護的方法,然後添加以下項目的AssemblyInfo文件

[assembly: InternalsVisibleToAttribute("[FQN of TestAssembly]")] 

這將使該項目的內部方法在屬性中指定的測試組件可見

2

我不知道,我看到這一點,一般在測試你的保護方法,不過,我不說TDD的觀點。一般而言,您的測試是針對該課程的公共方法編寫的。受保護的方法會在您重構代碼以提取內部使用的常用方法時出現。由於這些來自重構,您現有的測試已經覆蓋了重構的代碼。後來對通過公共專業化方法使用重構方法的代碼進行測試也會測試代碼 - 在這種情況下,專用化的公共方法在使用通用受保護方法時可以正常工作。

在少數情況下,一個受保護的方法的明確的測試是有道理的,我沒有看到在使用反射來進行試驗的危害。畢竟,你只是爲了測試的目的而打破封裝。

相關問題