恐懼用條件的排斥和循環是雙重的:
- 你可能有您的測試代碼中存在一個錯誤,所以測試不能正常運行,或者更糟糕的是,條件塊內部的斷言未被聲明。
- 這很難閱讀。
其他人已經通過複製和粘貼來硬編碼列表。我不喜歡這樣做,因爲它不僅會混淆測試,而且會使得以後重構變得更加困難。
如果代碼是像無形箭的回答是:
@Test
public void testsTotalPriceAsSumOfProductPrices() {
Products products = new Products(); // Or any appropriate constructor
products.add(new Product("first", 10)); // Assuming such a constructor exists
products.add(new Product("second", 20));
products.add(new Product("second", 30));
assertEquals("Sum must be eq to 60", 60, products.getTotalPrice());
}
而對於Product
構造改變,你就必須改變在許多不同的地方所有的測試代碼。
我更喜歡使幫助方法,使測試代碼更多的意圖揭示,並保持在重構過程中改變的地方的數量最少(希望只有一個)。
這難道不是更容易閱讀:
@Test
public void testsTotalPriceAsSumOfProductPrices() {
Products products = new Products();
addProductsWithPrices(products, 10,20,30);
assertEquals(60, products.getTotalPrice());
}
private static void addProductsWithPrices(Products products, Double...prices){
for(Double price : prices){
//could keep static counter or something
//to make names unique
products.add(new Product("name", price));
}
}
是這並使用for循環。但是如果你擔心它有缺陷或者輔助方法更復雜,你也可以爲它們編寫額外的測試!最終你可能想將這些輔助方法分解到他們自己的類中,以便它們可以在其他測試中重用。
此外,您可以看到測試方法隱藏了製作產品所需的其他字段(name
),與測試無關。我們的測試只關心價格,因此我們的助手只是填寫姓名,閱讀測試的人不會被額外的參數弄糊塗。很顯然,這個測試確保10 + 20 + 30 == 60。
最後,如果我們將價格從double
更改爲某種Currency
對象,我們只需要在一次位置進行更改,並且我們的測試代碼也是可讀的。
private static void addProductsWithPrices(Products products, Double...prices){
for(Double price : prices){
//could keep static counter or something
//to make names unique
products.add(new Product("name", Currency.valueOf(price)));
}
}
爲什麼不只是明確地添加(說)3個不同的產品與三個陳述?無論如何,這可能比循環更簡單。 –
我相信這不會成爲問題,但我想了解它背後的意義。如果我想用更多的物品測試它會怎樣?如果計算更復雜呢?通常,我想了解如何驗證在類中完成的操作,該操作使用項目列表計算特定值以及如何避免遍歷測試用例中作爲參數給出的所有項目。 –
你爲什麼要迭代* test *代碼?你可以在* real *代碼中迭代,但在測試代碼中,你可能只是硬編碼或者將其明確爲5 + 10 + 20或其他。並不是說我認爲迭代在測試中一定是一個問題 - 儘管「如果」條件至少是罕見的。儘管如此,我還是建議不要太教條。我更關心在貨幣數據中使用'double'... –