2009-11-06 121 views
16

我有一個名爲「Session」的類,它暴露了幾個公共方法。我想單元測試這些,但是在生產中我需要控制「會話」對象的實例化,所以將構造委派給SessionManager類並使Session的構造函數成爲內部。單元測試一個內部構造函數的類

我理想情況下喜歡從會話管理器中獨立地測試會話管理器,它創建會話管理器以證明會話公開的公共接口按預期工作 - 但不能在沒有使用的情況下從測試中實例化會話一個SessionManager讓我的測試比他們需要的更復雜/更少用處。

處理這個問題的最佳方法是什麼?

乾杯,

Lenny。

+0

普萊舍清晰起來:是它是受保護的___或內部構造函數? – 2009-11-07 11:25:01

回答

42

沒有什麼能阻止你從測試的內部簡單地讓你的代碼的內部可見的測試套件,使用InternalsVisibleTo屬性:。在集信息,加

[assembly:InternalsVisibleTo("TestSuiteAssembly")] 
+0

這似乎是最簡單的方法,所以我想我會用這個來運行。謝謝。 – 2009-11-07 15:10:48

+1

答案真的不完整 - 程序集必須簽名才能使其工作。 – Santhos 2014-02-19 14:08:08

+0

@Santhos不是真的... – 2016-10-06 21:30:18

2

你可以只讓你的單元測試類繼承會話(假設你的測試框架不要求你從一個特定的類繼承)。例如,對於NUnit的:

[TestFixture] 
public class SessionTest : Session 
{ 
    public SessionTest() 
     : base() // call protected constructor 
    { 
    } 

    [Test] 
    public void TestSomething() 
    { 
    } 

} 
+1

OP說ctor是內部的,不受保護。 – 2009-11-07 00:40:25

+0

@Rex - 問題的標題說保護,而問題本身說內部。 – 2009-11-07 00:44:14

1

你想用一個產品像TypeMock,這將允許您創建嘲笑(僞造)的類的實例,就像這樣:

var myInstance = Isolate.Fake.Instance<Session>(); 
// mock behavior here 
// do assertions here 

您可以創建實例爲了記錄,還需要使用TypeMock的抽象類。

+3

嘲笑你想測試的同一個班級對我來說沒有多大意義,雖然......你會不會測試模擬而不是班級呢? – Svish 2009-11-06 23:47:43

+0

@Svish,你是正確的,僞造的行爲沒有用,但它也可以創建實例並解決可訪問性問題:Isolate.Fake.Instance (Members.CallOriginal)。這樣你就有了一個類的實際實例,其構造函數是無法訪問的。 免責聲明 - 我在Typemock工作。 – Elisha 2009-11-07 12:45:50

2

另外,作爲一種解決方法,你可以只創建一個從會話繼承,並公開公共構造一個TestSession。在你的單元測試中,你使用TestSession,它基本上和最初的Session對象一樣。

public class TestSession : Session 
{ 

    public TestSession() : base() 
    { 

    } 

} 
1

我會質疑使會話類構造函數內部的價值。

通常這意味着你正試圖阻止其他開發者使用你的類。也許最好交流這個特定的應用程序如何工作,以及爲什麼你只想從會話管理器訪問會話?

+0

我已經看到它使用工廠模型做了很多工作,你可能想要強制該類只在一個地方創建或銷燬,但其他人可以引用它並使用它。 – 2009-11-06 23:48:21

+0

我也看到了很多:)我只是看不出它是如何增加任何價值的。當您想要擴展或測試時,它就會導致問題 - 就像倫納德現在正在經歷的一樣。 MS是這方面最糟糕的犯罪分子之一,有很多內部課程有時會有用,但我們無法訪問它們! Frustraing! – 2009-11-06 23:51:57

+5

作爲一個曾經是API消費者的人,並且非常沮喪,就像你想知道MS爲什麼會在內部做許多事情,受到保護等等。現在我主要做API開發,而我的東西被其他開發人員使用。我花了很多時間來清理別人的麻煩,因爲他們用自己內部的東西來解決問題。有時,期望能夠正確使用我們編寫的每一段代碼是不現實的。 – 2009-11-07 00:01:15

0

如果你可以用「受保護的內部」構造離開,那麼,假設你的測試是在不同的組件,你可以InternalsVisibleTo屬性添加到您的「待測試組裝」。這將使你的測試,看看內部成員將要測試的組裝」。

更新 出於某種原因,我讀了你的構造是受保護的,它使你在一個很好的位置,已經是內部使用該屬性