單元測試-JMockit中使用參數化(多參數)測試

開發人員在編碼完成之後,完善代碼的單元測試,有利於提高代碼質量,減少Bug數blablabla……….廢話不多說 直接上代碼:

//用於計算a+b+c
@Data
public class CalculatorAbc {

    private int a;
    private int b;
    private int c;
    private CalculatorAb calculatorAb;
    public int add(int a, int b, int c) {
        return calculatorAb.add(a,b) + c;
    }
}

//用於計算a+b
@Data
public class CalculatorAb {

    private int a;
    private int b;

    public int add(int a, int b) {
        return a + b;
    }
}

假設現在A程序員要測試自己寫的CalculatorAbc,但這個方法呢,又用到了B程序員寫的CalculatorAb,B有可能是通過dubbo調用的別人的服務,所以就要把B寫的calculatorAb.add()這個方法mocked掉,正常寫法:

@RunWith(JMockit.class)
public class CalculatorAbcTest {

    @Tested
    CalculatorAbc calculatorAbc;

    @Injectable
    CalculatorAb calculatorAb;

    @Test
    public void testAdd(){
        new NonStrictExpectations(){
            {
                calculatorAb.add(anyInt, anyInt);
                result = 5;
            }
        };
        int res = calculatorAbc.add(1,4,2);
        Assert.assertEquals(7, res);
    }
}

然後問題就來了,我要是測試多組數據怎麼辦,改入參,期望?不僅麻煩,而且測試數據沒有保存,再來看一下參數化(多參數)測試:

/**
 * 多參數測試
 */
@RunWith(Parameterized.class)
public class ParamCalculatorAbTest {

    private int expected;
    private int inputA;
    private int inputB;

    public ParamCalculatorAbTest(int expected,  int inputA, int inputB){
        this.expected = expected;
        this.inputA = inputA;
        this.inputB = inputB;
    }

    //參數數據準備
    @Parameterized.Parameters
    public static Collection<Object[]> t() {
        return Arrays.asList(new Object[][]{
                {8, 5, 3},
                {11, 7, 18},
                {0, 0, 0},
                {14, 8, 22}
        });
    }

    @Test
    public void testAdd() {
        CalculatorAb cal = new CalculatorAb();
        Assert.assertEquals(expected, cal.add(inputA, inputB));
    }

}

測試結果

利用參數化測試可以一次測試多組數據,測試數據生成位置統一,便於測試數據的準備和管理,也可通過文件讀取等方式加載,準備測試數據

這麼好的東西,不能和mocked結合怎麼行

/**
 * 參數化mocked測試
 */
@RunWith(Parameterized.class)
public class ParamCalculatorAbcTest {

    @Tested
    CalculatorAbc calculatorAbc;

    @Injectable
    CalculatorAb calculatorAb;

    private int expected;
    private int mocked;
    private int inputA;
    private int inputB;
    private int inputC;

    public ParamCalculatorAbcTest(int expected, int mocked, int inputA, int inputB, int inputC){
        this.expected = expected;
        this.mocked = mocked;
        this.inputA = inputA;
        this.inputB = inputB;
        this.inputC = inputC;
    }

    @Parameterized.Parameters
    public static Collection<Object[]> t() {
        return Arrays.asList(new Object[][]{
                {8, 5, 2, 3, 3},
                {11, 7, 2, 5, 4},
                {0, 0, 0, 4, 0},
                {14, 8, 4, 5, 6}
        });
    }

    @Test
    public void testAdd(){

        new NonStrictExpectations(){
            {
                calculatorAb.add(anyInt, anyInt);
                result = mocked;
            }
        };

        int res = calculatorAbc.add(inputA,inputB,inputC);

        Assert.assertEquals(expected, res);
    }
}

測試結果:
測試結果

這樣一來 所有的數據準備都可以放在@Parameterized.Parameters註解的方法下啦,把裏面的數字換成你想要的屬性或者對象,就可以一次完成多組數據的測試啦,最好能通過讀取文件的方式準備數據,也有利於測試數據的本地化和代碼的簡潔性~(編者本意:這次沒實現讀文件的數據準備,下次更上…)(或許這種方法比較挫氣,也或許有更好的方法,等待發掘…)
啦啦啦

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