2013-08-07 108 views
1

說冗餘的方法,主要的代碼,你有這樣的事情:跨越幾個單元測試/班

MyClass.java

public class MyClass { 
    public List<Obj1> create(List<ObjA> list) { 
     return (new MyClassCreator()).create(list); 
    } 
    // Similar methods for other CRUD operations 
} 

MyClassCreator.java

public class MyClassCreator { 
    Obj1Maker obj1Maker = new Obj1Maker(); 

    public List<Obj1> create(List<ObjA> list) { 
     List<Obj1> converted = new List<Obj1>(); 
     for(ObjA objA : list) 
      converted.add(obj1Maker.convert(objA)); 
     return converted; 
    } 
} 

Obj1Maker.java

public class Obj1Maker { 
    public Obj1 convert(ObjA objA) { 
     Obj1 obj1 = new Obj1(); 
     obj1.setProp(formatObjAProperty(objA)); 
     return obj1; 
    } 

    private String formatObjAProperty(ObjA objA) { 
     // get objA prop and do some manipulation on it 
    } 
} 

假設爲Obj1Maker單元測試已經完成,並涉及一種方法makeObjAMock()它嘲笑複雜的對象A.

我的問題:

  1. 單元測試MyClassCreator,我會怎樣測試create(List<ObjA> list)?所有的方法確實是將代碼從ObjA轉換爲Obj1,並在循環中運行它。轉換本身已經過測試。如果我要創建一個ObjA的列表並測試Obj1列表中的每個對象,那麼我必須將makeObjAMock()複製到MyClassCreator的單元測試中。顯然,這將是重複的代碼,所以正在使用verify()足以確保create(List list)的作用?

  2. 對於單元測試MyClass,它的create(List<ObjA>)方法再次將操作委託給MyClassCreator。我是否真的需要用完整的測試用例來測試它,還是應該驗證MyClassCreator的create方法是否被調用?

  3. 在Obj1Maker的單元測試中,我通過執行assertEquals(obj1.getProp(), formatObjAProperty(objA))來檢查屬性Obj1和ObjA是否相互對應。但是,這意味着我不得不將Obj1Maker類中私有方法formatObjAProperty的代碼複製到其單元測試中。在這種情況下如何防止代碼重複?我不想公開/保護這種方法,所以我可以在單元測試中使用它。在這種情況下重複是否可以接受?

謝謝,並且對冗長的問題感到抱歉。

回答

0

我的意見就在這裏。選擇要測試的方法是一件很難的事情。

您必須考慮a)您是否滿足您的要求,以及b)將來有人愚蠢更改代碼時會出現什麼問題。 (實際上,愚蠢的人可能是你,我們都有不好的日子。)

我會說,編寫新代碼來驗證兩個對象具有兩種格式的相同數據將是一個好主意。可能沒有理由複製私有方法的代碼,並且複製代碼是一個壞主意。請記住,您正在驗證需求。因此,如果原始字符串說:「13年6月30日」,並重新格式化的一個說:「2013年6月30日」,我只想硬編碼檢查:

assertEquals("Wrong answer", "June 30th 2013", obj.getProp()); 

添加一些斷言的邊緣情況和錯誤。(在我的例子中,使用「2/30/13」和「2/29/12」和「12/1/14」來檢查非法日期,閏年日,並且它可能得到「1st」而不是「1th」。 )

在對create方法的測試中,我可能只是爲了簡單的錯誤,並驗證返回的數組與傳入的數組的數目相同。我傳入的數組中有兩個相同的元素,一些不同的。我只是檢查相同的回來相同和不同的不相同。爲什麼?因爲我們已經知道格式化程序的作用。

我不會測試構造函數,但會確保一些測試運行它中的代碼。確保大部分代碼實際上在測試中運行以捕獲像錯過的空指針這樣的愚蠢錯誤是很好的。

平衡點就是你要找的。

足夠的測試,測試足夠多的不同的東西,感覺良好的代碼工作。

足夠的測試,測試明顯的事情,在未來會發現愚蠢的變化。

沒有太多的測試,測試需要永久運行,所有開發人員(包括您)都會推遲運行它們,因爲他們不想在運行時等待或失去思路。

平衡!