2012-02-20 224 views
3

複製測試類中​​的代碼是否「不好」?正如你所看到的,我將駕駛記錄添加到駕駛記錄中,以便有多種方法進行測試。將這個提取到一個私人幫手方法會更好嗎?還是更清楚地保持它的樣子?你在這種情況下做什麼?在JUnit測試中重複代碼

@Test 
public void shouldRemoveAllDrivingRecords() { 
    Duration duration1 = new Duration(1, 30, 45); 
    Duration duration2 = new Duration(2, 50, 12); 

    DrivingRecord drivingRecord1 = new DrivingRecord(230.0, duration1, "This was a long trip"); 
    DrivingRecord drivingRecord2 = new DrivingRecord(300.0, duration2, "This trip is even longer."); 

    drivingLog.addDrivingRecord(drivingRecord1); 
    drivingLog.addDrivingRecord(drivingRecord2); 

    drivingLog.removeAllDrivingLogs(); 

    assertEquals(0, drivingLog.numberOfDrivingRecords()); 
} 

@Test 
public void shouldSumTheDistanceDriven() { 
    Duration duration1 = new Duration(1, 30, 45); 
    Duration duration2 = new Duration(2, 50, 12); 

    DrivingRecord drivingRecord1 = new DrivingRecord(230.0, duration1, "This was a long trip"); 
    DrivingRecord drivingRecord2 = new DrivingRecord(300.0, duration2, "This trip is even longer."); 

    drivingLog.addDrivingRecord(drivingRecord1); 
    drivingLog.addDrivingRecord(drivingRecord2); 

    double expectedDistanceDriven = drivingRecord1.getDistance() + drivingRecord2.getDistance(); 
    double totalDistanceDriven = drivingLog.getDistanceDriven(); 

    assertEquals(expectedDistanceDriven, totalDistanceDriven, 0.1); 
} 

回答

6

在任何地方複製代碼是「不好」的。此代碼是否因某個原因而重複,或僅僅是方便嗎?如果同時希望在兩者中使用相同的數據並以相同的方式添加它,那麼稍微的「設置」方法是有道理的。

1

代碼複製總是很糟糕,沒有問號。 爲了避免它在你的情況下,編寫可重用的測試場景,然後從@Test註釋與具體參數註解的方法調用它(實現方案,並接受參數私有方法)。

@Test 
public void shouldRemoveAllDrivingRecords() { 
    theTest(0); 
} 

@Test 
public void shouldSumTheDistanceDriven() { 
    theTest(0.1); 
} 

如果需要,您還可以創建TestSuites。這允許您使用不同的參數運行測試組。

1

我想,如果需要在類或以其他方式私有輔助方法,所有的測試方法的代碼,我們應該總是將它解壓到任意setUp()方法。

0

我跟着幹prinicple也JUnit中!我甚至還有作家助手或建造者班做重複任務。一個好的Junit的方法應該第一眼只包含數據,因此很明顯什麼沒有污染它是如何測試進行測試。

5

可以註釋與@org.junit.Before的方法和在該方法中初始化變量:

public class DrivingLogTest { 
    //suposing DrivingLog class... 
    private DrivingLog drivingLog; 

    private Duration duration1; 
    private Duration duration2; 

    private DrivingRecord drivingRecord1; 
    private DrivingRecord drivingRecord2; 


    @Before 
    public void setUp() { 
     drivingLog=new DrivingLog(); 
     duration1 = new Duration(1, 30, 45); 
     duration2 = new Duration(2, 50, 12); 

     drivingRecord1 = new DrivingRecord(230.0, duration1, "This was a long trip"); 
     drivingRecord2 = new DrivingRecord(300.0, duration2, "This trip is even longer."); 

     drivingLog.addDrivingRecord(drivingRecord1); 
     drivingLog.addDrivingRecord(drivingRecord2); 

    } 


    @Test 
    public void shouldRemoveAllDrivingRecords() { 

     drivingLog.removeAllDrivingLogs(); 

     assertEquals(0, drivingLog.numberOfDrivingRecords()); 
    } 

    @Test 
    public void shouldSumTheDistanceDriven() { 

     double expectedDistanceDriven = drivingRecord1.getDistance() + drivingRecord2.getDistance(); 
     double totalDistanceDriven = drivingLog.getDistanceDriven(); 

     assertEquals(expectedDistanceDriven, totalDistanceDriven, 0.1); 
    } 
} 
2

單元測試代碼是產品代碼,正如上面的答案中所述,所有的代碼重複都應該避免。

我通常做的是要麼使用@Before方法對於所有變量初始化,或使用可以將多個單元測試/項目之間共享的TestUtility類。

5

我敢說大部分的答案不同意,對我測試代碼一樣的生產代碼。當然,測試代碼與生產代碼一樣值得同樣的關注和關注,因爲它是整體開發工作的一部分,但它們本質上是不同的。我不會重複自己,而是指向我的另一個答案:Is it OK to copy past unit test when logic is the same

也就是說,重複創建測試數據是壞的。更好的辦法是考慮爲測試精心創建的數據集,並支持測試大多數情況。該數據集可以在setUp方法中創建。如有必要,可以有多個測試數據集,涵蓋業務規則的變體。創建有用的測試數據集並不容易,但值得花一些時間。另外,測試數據可以從JSON或者其他軟件加載。在某些情況下,維護起來更容易。

單元測試通常不應該相互依賴。但經常,測試用例確實互相依賴。例如,要測試一個列表,一個想測試的是add()作品,即isEmpty()作品,即remove()的作品。測試remove()假設add()工作。對於這種情況,您可以使用JExample,這是一個單元測試框架,您可以通過它來「鏈接」測試。

0

將所有常見配置提取到@before。你也可以使用參數,@Parametrized或者我的項目:zohhak,例如。

@Before 
public void prepareBank() { 
    ... 
} 

@TestWith({ 
    "25 USD", 
    "38 GBP", 
    "null" 
}) 
public void testMethod(Money money) { 
    ... 
}