Java單元測試框架JUnit的基本使用

Java單元測試框架JUnit的基本使用

單元測試十分重要!尤其是微服務web之類的複雜項目,這類項目代碼的嵌套層次多,方法層數多,如果不做單元測試,功能完成之後bug的數量級肯定會很大。如果你有非常嚴格的單元測試,每寫一個方法,每完成一模塊或者功能,都進行了單元測試,那麼在業務功能整體完成之後,你就會發現你基本不可能出現bug。單元測試的好處非常多,還可以極大的減少程序後期的維護成本和工作量。有了成套的單元測試,後期改代碼排查問題,你就不用一遍一遍的讀代碼了,直接跑一遍單元測試就知道大概了。

1. 安裝使用

maven配置,簡單而俗套

 <!-- https://mvnrepository.com/artifact/junit/junit -->
 <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.13</version>
   <scope>test</scope>
 </dependency>

2. 實例待測試代碼

一個別人寫好的計算類,做實例用的,參考價值還可以,拿來直接用。

public class Calculator {
    public int calculate(String expression) {
        String[] ss = expression.split("\\+");
        System.out.println(expression + " => " + Arrays.toString(ss));
        int sum = 0;
        for (String s: ss) {
            sum += Integer.parseInt(s.trim());
        }
        return sum;
    }
}

3. 編寫測試類

大體的結構基本在創建項目的時候,Maven原型已經給你創建好了,具體的細節目錄和包結構因人而異,可以隨意發揮。

import org.junit.Test;
import static org.junit.Assert.*;

public class CalculatorTest {
    @Test
    public void calculate() {
        assertEquals(4, new Calculator().calculate("1 + 2"));
        assertEquals(6, new Calculator().calculate("1 + 2 + 3"));
    }
}

4. 常用的斷言方法

  • assertEquals(100, x): 斷言相等
  • assertArrayEquals({1, 2, 3}, x): 斷言數組相等
  • assertEquals(3.1416, x, 0.0001): 浮點數組斷言相等
  • assertNull(x): 斷言爲null
  • assertTrue(x > 0): 斷言爲true
  • assertFalse(x < 0): 斷言爲false;
  • assertNotEquals: 斷言不相等
  • assertNotNull: 斷言不爲null

5. 單元測試邏輯結構

  1. 在@Before方法中初始化測試資源
  2. 在@After方法中釋放測試資源
  3. @BeforeClass: 初始化非常耗時的資源, 例如創建數據庫
  4. @AfterClass: 清理@BeforeClass創建的資源, 例如創建數據庫
  5. 對於每一個@Test方法的執行順序
  • 單個@Test方法執行前會創建新的XxxTest實例, 實例變量的狀態不會傳遞給下一個@Test方法,
  • 單個@Test方法執行前後會執行@Before和@After方法
  1. 執行順序
  • 執行類的構造函數=>執行@Before方法=>執行@Test方法=>執行@After方法
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class SequenceTest {

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        System.out.println("BeforeClass()");
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        System.out.println("AfterClass()");
    }

    @Before
    public void setUp() throws Exception {
        System.out.println("    Before()");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("    After()");
    }

    public SequenceTest() {
        System.out.println("  new SequenceTest()");
    }

    @Test
    public void testA() {
        System.out.println("    testA()");
    }

    @Test
    public void testB() {
        System.out.println("    testB()");
    }

}

6. 參數化測試

@RunWith: 當類被@RunWith註釋修飾, 或者類繼承了一個被該註解類修飾的類, JUnit將會使用這個註解所指明的運行器(runner)來運行測試, 而不是JUni默認的運行器
要進行參數化測試,需要在類上面指定如下的運行器:@RunWith (Parameterized.class)
然後,在提供數據的方法上加上一個@Parameters註解,這個方法必須是靜態static的,並且返回一個集合Collection。
具體詳細說明如下:

  1. 測試類必須由Parameterized測試運行器修飾
  2. 準備數據。數據的準備需要在一個方法中進行,該方法需要滿足一定的要求:
  • 該方法必須由Parameters註解修飾
  • 該方法必須爲public static的
  • 該方法必須返回Collection類型
  • 該方法的名字不做要求
  • 該方法沒有參數
@RunWith(Parameterized.class)
public class TestParams {

    @Parameterized.Parameters
    public static Collection<?> data() {
        return Arrays.asList(new Object[][] { { "1+2", 3 }, { "1+2+3", 8 }, { "123+456", 579 }, { " 1 + 5 + 10 ", 16 } });
    }

    Calculator calc;

    @Parameterized.Parameter(0)
    public String input;

    @Parameterized.Parameter(1)
    public int expected;

    @Before
    public void setUp() {
        calc = new Calculator();
    }

    @Test
    public void testCalculate() {
        int r = calc.calculate(this.input);
        assertEquals(this.expected, r);
    }

}

7. 其他常用測試

7.1 異常測試

異常測試可以通過@Test(expected=Exception.class), 對可能發生的每種類型的異常進行測試

  • 如果拋出了指定類型的異常, 測試成功
  • 如果沒有拋出指定類型的異常, 或者拋出的異常類型不對, 測試失敗
// 發生了ArithmeticException異常, 代碼通過
@Test(expected = ArithmeticException.class)
    public void testException() {
       int i = 1 / 0;
    }
7.1 超時設置

在測試類的方法上使用 @Timeout 註解,測試類的所有方法應用 Timeout 規則
@Test(timeout=1000)可以設置超時時間,單位是毫秒
@Timeout 註解來測試任意特定方法的執行時間。如果測試方法的執行時間大於指定的超時參數,測試方法將拋出異常,測試結果爲失敗。指定的超時參數是以毫秒記。

mport org.junit.*;

public class TimeOutTest {

	@Test(timeout = 1000)  
	public void infinity() {  
		while (true);  
	}   
}

8. 參考教程

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章