2014-09-19 203 views
1

我是軟件測試的新手。在教程中,我讀,我可以測試一些像這樣的方法:測試返回類型的方法void

@Test 
public void testMultiply() { 
    MyClass tester = new MyClass(); 
    assertEquals("10 x 5 must be 50", 50, tester.multiply(10, 5)); 
} 

所以我有一些參數傳遞給方法,並得到一個返回值。
但在我來說,我有一些類不帶任何參數和返回值:

ArrayList al = new ArrayList(); 

public void Main(){ 
    methodA(); 
    methodB(); 
} 

public void methodA(){ 
    // connect to URL 
    // get some data 
    for(int i=0; i<someThing; i++){ 
    al.add(data); 
    } 
} 
public void methodB(){ 
    // do something with al 
} 

是否也可以對它們進行測試?例如,正確的值是否來自methodA()中的URL。

+0

當然可以。它看起來像'methodA()'正在修改'ArrayList'的內部狀態,所以你可以讓你的測試類在執行該方法之前和之後檢查列表的內容。 – azurefrog 2014-09-19 19:03:56

+0

是的,它取決於什麼是重要的,你可以使用mockito來驗證實現是否被調用,或者你可以驗證它發生變異的對象。 – StackFlowed 2014-09-19 19:04:05

+0

當然。通常,如果在沒有參數和返回值的情況下調用函數期間沒有發生錯誤,則表示該函數可以工作。當然,這根本不是真的。爲此,您可以簡單地使用調試器並測試程序的流程。 – nbro 2014-09-19 19:04:06

回答

4

可以測試不返回任何東西的方法(void),但是您必須測試該方法的副作用。它應該有一些副作用,否則這種方法是沒用的。

這裏的副作用是al已更改。正如所寫的,這個類沒有任何其他暴露al的方法。添加一個getter方法,該方法返回ArrayListArrayList的特定元素。然後,您的測試方法可以調用getter方法來檢索值並將其與預期值進行比較。

+1

我應該僅添加此方法,以便測試類可以調用它?即使我實際上並不需要它在我的代碼中? – user1170330 2014-09-19 20:14:43

+0

這些數據是如何使用的?如果其他方法(如methodB)使用它,則可以使用'methodB'並測試其副作用。 – rgettman 2014-09-19 20:22:06

+0

@ user1170330是的。你正在編寫一個可測試的組件,這意味着要編寫足夠的訪問器來測試它。如果這些不應該在生產中被調用,請將它們記錄下來。 – 2014-09-19 20:37:34

1

方法不帶參數用於其返回值或它們的副作用。因此,這些方法中的測試包括以下三個步驟:

  • 設置對象正被試驗的初始狀態調用參數方法
  • 調用參數方法
  • 檢查返回值或副作用之前的無參數方法

最後一步可以檢查被測試對象的新狀態或其在系統的整體環境中的工作結果。

這裏是一個小例子:

class Calculator { 
    private int left, right, result; 
    public void setLeft(int val) { left = val; } 
    public void setRight(int val) { right = val; } 
    public int getResult() { return result; } 
    public void add() { result = left + right; } 
    public void multiply() { result = left * right; } 
} 

你可以測試其multiply()方法是這樣的:

@Test 
public void testMultiply() { 
    // Set the object being tested to the initial state 
    Calculator tester = new Calculator(); 
    tester.setLeft(5); 
    tester.setRight(10); 
    // Call the method 
    tester.multiply(); 
    // Check the new state 
    assertEquals("10 x 5 must be 50", 50, tester.getResult()); 
} 

方法的這種抽樣檢驗的副作用。測試的方法有返回值,無副作用將結合其在斷言線檢查方法的調用。

+0

值得澄清:無參數*或返回值*的方法用於其副作用。沒有參數但帶有返回值的方法不需要有副作用(例如getter方法)。 – 2014-09-19 19:14:23

+0

@ chiastic-security這是一個公正的觀察,非常感謝! – dasblinkenlight 2014-09-19 19:17:35

0

在這種情況下,你想測試呼叫,而不是輸出(例如,返回值)的調用本身的副作用。

  1. 如果副作用是可見的,測試他們的結果符合您的預期
  2. 如果副作用是不容易看到,因爲它們調入外部接口:您可以在許多不同的方式測試這個,使用mocking frameworkPowerMock與模擬對象來代替外部接口,這樣就可以對來電觀察和測試,外部接口
  3. 重新設計你的界面更加可測試。:)

在你的具體情況下,我會添加一個訪問器,並檢查其調用AMethod()後的預期內容。

一般來說,對於單元測試,您不希望連接到外部URL,數據庫等,因爲它很慢且很昂貴。您想用可以模擬它們的數據提供者替換這些調用。

1

是的,你當然可以測試一個沒有參數的方法。

這可能是一個例子是看到這個最好的方法。考慮一下ArrayList.clear()方法。它的作用是清空ArrayList,以便其大小爲零。您將通過以下方式測試此方法:

  1. 創建ArrayList arr;
  2. 添加一些東西給它;
  3. 調用arr.clear();
  4. 檢查assertEquals(arr.size(),0)

換句話說,你設置的東西了,這樣你的ArrayList有一個狀態,你不希望(size()>0);那麼你正在調用應該對狀態產生可預測影響的方法(設置size()0);然後檢查效果是否符合您的預期。

+0

如果在我的實現中實際上不需要方法size()會怎麼樣?我應該創建它以便測試課程可以使用它嗎? – user1170330 2014-09-19 19:19:08

+0

嗯,重點在於被測試的方法必須對狀態有一定的影響,並且狀態的改變必須能夠用已經存在的方法檢測到,否則該方法是毫無意義的,或者您需要一些更多的方法!換句話說,如果你沒有任何依據你是否清除了'ArrayList'而採取不同行爲的方法,那麼清除它就永遠沒有任何意義。 – 2014-09-19 19:25:13

1

是的,你可以測試這些方法,如果你在其他方法中使用這些方法作爲副作用。 作爲示例 -

public class test{ 
public int i=0; 
public void incrementIngeterValue() 
{ 
    //doing something and 
    i++; 
} 

public boolean incremented() 
{ 
    //some logic to check what is current i value 
    int x = incrementIngeterValue(); 

    if(x==i) 
     return false; // value not incremented 
    else 
     return true // in this case you can make sure this value is incremented by 1. 


} 

所以,你可以檢查我的值增加1或不用,用這種方法,你在內部沒有參數和返回值測試incrementIngeterValue()測試遞增方法。

在你的情況下,你的a1受到兩種方法的影響。某處你正在使用這個a1。

相關問題