2009-01-07 43 views
14

我有一門課,我正在用DUnit進行單元測試。 它有一些公共方法和私人方法的一些方法。如何使用DUnit測試私有方法?

type 
    TAuth = class(TDataModule) 
    private 
    procedure PrivateMethod; 
    public 
    procedure PublicMethod; 
    end; 

爲了編寫這個類的單元測試,我必須公開所有的方法。

是否有不同的方法來聲明私有方法,以便我仍然可以測試它們但它們不公開?

+0

另請參見:[使用JUnit使用私有方法測試類的正確方法是什麼?](http://stackoverflow.com/questions/34571/whats-the-proper-way-to-test-a-class -with-private-methods-using-junit) – mjn 2012-11-15 12:24:14

+0

另一個選項http://stackoverflow.com/questions/7525071/accesing-a-strict-private-field-using-the-rtti – sav 2014-12-11 02:21:51

+0

可能的重複[如何測試一個具有私有方法,字段或內部類的類?](https://stackoverflow.com/questions/34571/how-do-i-test-a-class-that-has-private-methods-fields-or-內部類) – Raedwald 2017-12-14 13:08:02

回答

19

您不需要公開它們。受保護會做。然後,您可以爲類進行子類型的單元測試,並顯示受保護的方法。例如:

type 
    TAuth = class(TDataModule) 
    protected 
    procedure MethodIWantToUnitTest; 
    public 
    procedure PublicMethod; 
    end; 

現在你可以亞型它爲你的單元測試:

interface 

uses 
    TestFramework, Classes, AuthDM; 

type 
    // Test methods for class TAuthDM 
    TestAuthDM = class(TTestCase) 
    // stuff 
    end; 

    TAuthDMTester = class(TAuthDM) 
    public 
    procedure MethodIWantToUnitTestMadePublic; 
    end; 

implementation 

procedure TAuthDMTester.MethodIWantToUnitTestMadePublic; 
begin 
    MethodIWantToUnitTest; 
end; 

但是,如果進行單元測試所需的方法與數據模塊做事如此密切,它是不是安全除了私有的東西外,你應該考慮重構這些方法,以便分離需要進行單元測試的代碼和訪問數據模塊內部的代碼。

4

我由Gerard梅薩羅斯建議 「XUnit Test Patterns」 書:

Test-Specific Subclass

問題:我們怎樣才能使代碼 可測試的時候,我們需要訪問SUT的 私有狀態?

:添加露出 狀態或行爲由測試 需要對SUT的子類的方法。

...如果被測(SUT)系統不 專門設計,可測試的, 我們可能會發現,測試無法得到 進入狀態,它必須 初始化或 的在某些時候驗證測試。

該文章還解釋了何時使用它以及它承載哪些風險。

4

將DUnit代碼放入您的設備中。然後你可以訪問任何你喜歡的東西。

7

這是一個有點哈克,但我喜歡用這個條件編譯指令:

{$IfNDef TEST} 
    private 
    {$EndIf} 

你的單元測試項目應在project → conditional defines定義測試。

沒有可見性規範,它們就會被髮布。注意:如果私有可見性不是類聲明中的第一個,它將得到先前的定義。一個更安全的方式,但更冗長,不太清楚,應該是:

private 
    {$IfDef TEST} 
    public 
    {$EndIf} 

這已超過了子類或其他方法的一些優點:

  • 沒有額外的複雜性:在你的代碼中沒有額外的類
  • 沒有人可以「錯誤地」劃分子類並覆蓋你的類:你保留了你的體系結構
  • 當你說一個方法被保護時,你有點期待它被覆蓋。你在告訴這是誰在閱讀你的代碼。一個不應該被覆蓋的受保護的方法會讓你的代碼閱讀器感到困惑,打破了我的第一個編程原則:「代碼必須被寫入以供其他人讀取」。
  • DUnit是在他們自己的單位,沒有包括到處
  • 你不碰凌亂的RTTI。

我認爲這是一個更清晰的解決方案,並比選定的答案更好。

當我使用這個時,我還配置了測試項目,將構建對象放在主項目的不同目錄中。這可以防止帶有TEST指令的二進制文件與其他代碼混合。

4

一般來說,當我遇到這種情況時,我經常意識到我違反了單一責任原則。當然,我對你的具體情況一無所知,但馬伊貝認爲私人方法應該屬於他們自己的階級。 TAuth不會在私人部分提到這個新班級。

1
{$IFNDEF UNITEST} 
private 
{$ENDIF} 

簡單的解決方案,這幾乎是一個黑客的收視率最高的答案。我經常需要測試私有方法,這種技術儘可能避免了複雜性。