2016-04-09 44 views
1

對於構建單元測試或測試用例,我不是很有經驗,現在我需要一些建議。我有這門課我打算做,但我不確定單元測試的最佳方式是什麼。我沒有寫的類尚未但它會是這個樣子:Java - 需要關於如何對這個類進行單元測試的建議

public class ClassName { 

    private ArrayList<Order> sortedOrderList1 = new ArrayList<>(); 
    private ArrayList<Order> sortedOrderList2 = new ArrayList<>(); 

    public void method1(Order order) { 
     //Modifies Order objects inside sortedOrderList1 or sortedOrderList2. 
    } 

    public method2(Order order) { 
     //Modifies Order objects inside sortedOrderList1 or sortedOrderList1. 
    } 
} 

名單內的Order對象有pricequantity。這些方法將進入列表並從quantity中減去列表末尾的一些Order對象,並刪除quantity達到0的對象。

現在問題是我不知道什麼是測試這些方法的最佳方法是。在我的JUnit類中,我將無法訪問private列表,並且這些方法本身沒有返回值供我檢查。測試這些方法的最佳實踐方法是什麼?

+0

你如何設置'sortedOrderList1'和'sortedOrderList2'? –

+4

你必須考慮這些訂單來自哪裏以及去哪裏。他們不僅僅是在內部創建,從來沒有看到白天的光明,對嗎? –

+1

更好的問題可能是你想要做什麼?有時候單元測試很難寫,這意味着你應該重構你的代碼。在某些情況下,首先編寫測試可能會很有幫助(這明確定義了您正在嘗試執行的操作)。然後編寫使這些測試通過的代碼。見TDD。 – cyroxis

回答

1

您應該爲這兩種公共方法創建單元測試。如果這些方法對訂單對象進行更改,它們作爲參數傳遞,那麼您的單元測試應該對該對象進行斷言。你也應該檢查sortedOrderLists的狀態。

您將有一點點問題,以抓住這些排序的順序列表來檢查它們。以下是三種可能的解決方案

第一個選項,如果由於某種原因你不能或不想改變你的類的實現。你將不得不使用反射來獲得對這些私人領域的引用。

第二個選項是將這些字段的可見性更改爲受保護的。然後在同一個包中創建單元測試類。現在可以直接找到排序的訂單列表。

第三種也許是最好的選擇是對這些字段使用依賴注入。依賴注入有很多不同的選項。你可以使用CDI或Spring類似的東西。但爲了保持簡單,您可以使用純java設置器或構造器注入。只是不要在課堂上列出這些名單。既然你注入了這些列表,現在他們甚至可以是私人的。你的單元測試課程將創建這些列表並將它們注入到你的課程中。現在您可以在這些專用字段中找到引用,並可以使用斷言來檢查它們。

例與構造器注入:

public class ClassName { 

    private ArrayList<Order> sortedOrderList1; 
    private ArrayList<Order> sortedOrderList2; 

    public ClassName(ArrayList<Order> sortedOrderList1, ArrayList<Order> sortedOrderList2) { 
     this.sortedOrderList1 = sortedOrderList1; 
     this.sortedOrderList2 = sortedOrderList2; 
    } 

    public void method1(Order order) { 
     //Modifies Order objects inside sortedOrderList1 or sortedOrderList2. 
    } 

    public method2(Order order) { 
     //Modifies Order objects inside sortedOrderList1 or sortedOrderList1. 
    } 
} 

例單元測試:

import org.junit.Assert; 

public class ClassNameTest { 

    public void testMethod1() { 
     ArrayList<Order> list1 = new ArrayList<>(); 
     ArrayList<Order> list2 = new ArrayList<>(); 
     Order order = new Order(); 
     ClassName testMe = new ClassName(list1, list2); 
     testMe.method1(order); 
     // Insert your assertions for example: 
     Assert.assertTrue(list1.contains(order)); 
    } 

} 
1

如果如你所描述的階級它並沒有別的,那麼你可能也沒有單元測試它,因爲它是無用。爲了使代碼有用,它必須返回一個值,更改狀態或可能的兩者。在您的示例中,您正在修改狀態,以便您的測試需要驗證狀態更改是否正確發生。現在,您必須修改狀態才能實現某種目的,即另一種方法返回該數據或將其發送到某處 - 是您如何測試代碼的單元。

UPDATE

基於從OP的詳細信息有打印的訂單STDOUT的方法。這符合上面提到的副作用函數。在這種情況下,您會希望提供一種對STDOUT的抽象,您可以從您的測試中嘲笑/僞造,然後驗證更新的訂單是否能夠正確實現。

+0

這是一個命令行應用程序,並且這些方法將打印他們對列表進行的修改以生成標準輸出。用戶可以輸入命令以打印所有訂單,也可以輸入命令以添加訂單或從訂單中刪除數量。所以數據發送/輸出的唯一地方就是標準輸出。 –

+0

在這種情況下,測試讓你知道一些關於你的設計的東西(這些信息在原始文章中也是有用的)。我會更新我的答案以反映這一點 – tddmonkey

相關問題