簡體   English   中英

將私人成員更改為默認進行測試

[英]Change private member to default for testing

將私有類成員更改為默認(程序包訪問)以測試其行為是否是個好主意? 我的意思是測試用例應在測試目錄中定位,但應與被測試成員的類位於同一包中。

編輯:你們說的都是真的。 但是類通常具有輔助私有方法。 而且這些方法可能很復雜,因此需要進行測試。 太糟糕了-測試公共方法以確保正確處理私有復雜方法。 你不是這樣嗎

我通常更喜歡以對公共API編寫測試有意義的方式編寫類和測試。 因此,基本上,我是說如果您需要訪問被測類的私有狀態,那么您可能已經參與了該類的內部測試。

不,不是。 因為更改測試對象可能會更改結果。 如果您確實需要在測試期間調用私有成員或方法,則添加訪問器更為安全。 這仍然會改變類別,但風險較低。 例:

private void method() { /* ... */ }

// For testing purpose only, remove for production
@Deprecated  // just another way to create awareness ;)
void testMethod() {
   method();
}

OK-如果需要測試私有方法,則可以采用另一種解決方案:可以使用反射和實例化API調用任何方法。

假設,我們有:

public class SomeClass {
  private Object helper(String s, String t) { /* ... +/ }
}

然后我們可以像測試

@Test public void testHelper() {
   try {
     SomeClass some = new SomeClass();
     Method helperMethod = some.getClass().getDeclaredMethod("helper", String.class, String,class);
     helperMethod.setAccessible(true);
     Object result = helperMethod.invoke(some, "s", "t");
     // do some assert...

   catch(Exception e) {
     // TODO - proper exception handling
   }
}

我了解您需要測試私有方法的意思,並且我也明白了為什么人們只說測試公共方法。 我剛剛遇到了一些遺留代碼,這些遺留代碼具有許多私有方法,其中一些被公共方法調用,但是一些是線程或被線程調用,它們在構造對象時啟動。 由於代碼到處都是錯誤,並且缺少任何注釋,因此我不得不測試私有代碼。 我已經使用這種方法解決了這個問題。

   MainObject.cs
    class MainObject
    {
        protected int MethodOne();    // Should have been private.
        ....
    }
    TestMainObject.cs
    class ExposeMainObject : MainObject
    {
        public int MethodOne();
    }
    class TestMainObject
    {
        public void TestOne()
        {
        }
    }

由於沒有交付測試對象,因此看不到問題,但是如果有請告訴我。

測試勝過隱私修改器。 確實,某個方法的可見度“過高”導致的bug多久發生一次? 與未經過完全測試的方法引起的錯誤相比?

如果Java具有C ++之類的“朋友”選項,那就太好了。 但是語言的限制絕不能成為不測試的借口。

邁克爾·費瑟斯(Michael Feathers)在“有效地使用舊版代碼”(優秀著作)中的這場辯論中大聲疾呼,並暗示這可能是想要提取(並具有公共方法)的子類的味道。

在我們的商店( 〜1M LOC)中,我們將“ private”替換為“ / TestScope /”,以指示方法應有效地私有,但仍可測試。

試圖用反射規避“私人”是恕我直言,這是一種氣味。 這使得測試難以編寫,閱讀和調試,以保留隱私的“迷信”,無論如何您都在努力。 何必呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM