1. 程式人生 > >Junit單元測試

Junit單元測試

ora final類 state isalive -s 查詢 string 順序 new

LLT是測試系統的一部分,主要是由代碼開發人員來編寫,Mock的意思是效仿模仿的意思,就是最測試過程中不需要的一些類和方法模擬出相應的返回值,稱為打樁,測試關註的是一個類或方法的結果而不是過程調用,打樁涉及到不同的類,有返回值、無返回值、參數驗證、靜態類靜態方法、final方法等不同的方式。

流行的Mock工具如jMockEsayMockMockito等不能mock靜態、final、私有方法

PowerMock中的註釋

1. 程序運行順序註釋

1)Test將一個普通的方法裝飾成為一個測試方法

2)@BeforeClass 它會在所有的方法運行之前進行執行,static修飾

3)@AfterClass 它會在所有的方法運行結束之後進行執行,static修飾

4)@Before 會在每個測試方法運行之前執行一次

5)@After 會在每個測試方法運行之後執行一次

其中@Before @Test @After 這三個標簽是組成執行的。有幾個@Test,就會執行多少次。

2. 其他運行註解

1)@RunWith 可以修改測試運行期 org.junit.runner.Runner,當需要mock私有方法調用的私有方法是,需要加上@RunWith(PowerMockRunner.class)

2)@PrepareForTest 在使用mock是,首先要在該項添加mock的類@PrepareForTest({類名.class})

@PrepareForTest 註解和@RunWith註解是結合使用的,不要用單獨使用它們中的任何一個,否則不起作用,當使用PowerMock和去mock靜態,final或者私有方法時,需要機上兩個註解。

常用的Mock方法:

1.Mock普通對象(有返回值)

1 public class Calculator{
2     public int Add(int a, int b){
3         return a + b;
4     }
5 }

Mock方法如下(這裏不需要添加PrepareForTest 和RunWith註解)

1 @Test
2 public void
testAdd(){ 3 Calculator calculator = PowerMockito.mock(Calculator.class); 4 PowerMockito.when(calculator.Add(Mockito.anyInt(), Mockito.anyInt())).thenReturn(10); 5 assertEquals(10, calculator.Add(1, 1)); 6 }

2. Mock普通對象(無返回值)

1 public class Calculator{
2     public void print(){
3         System.out.println("Hello World");
4     }
5 }

Mock方法如下(這裏不需要添加PrepareForTest 和RunWith註解)

1 @Test
2 public void testPrint(){
3     Calculator calculator = PowerMockito.mock(Calculator.class);
4     PowerMockito.doNothing().when(calculator).print();
5     calculator.print();
6     //驗證Mock對象被調用
7     Mockito.verify(calculator).print();
8 }

3. Mock靜態方法

1 public class ClassThatContainsStaticMethod(){
2     public static String getUserName(int id){
3         String string = "UserName" + id;
4         return string;
5     }
6 }

Mock方法如下(這裏不需要添加PrepareForTest 和RunWith註解)

 1 @RunWith(PowerMockito.class)
 2 @PreparaForTest(ClassThatContainsStaticMethod.class)
 3 pulic class testClassThatContainsstaticMethod{
 4     @Test
 5     public void testGetUserName() throws Exception{
 6         PowerMockito.mockStatic(ClassThatContainsStaticMethod.class);
 7         PowerMockito.when(ClassThatContainsStaticMethod.getUserName(Mockito.anyInt())).thenReturn(null);
 8         assertEquals(ClassThatContainsStaticMethod.getUserName(123), null);
 9     }
10 }

4. Mock私有方法

使用PowerMockito.method獲取Method對象調用私有方法,除此之外,還有Whitebox.InvokeMethod直接調用,在此不做說明;

1 public class Calculator{
2     private int addPrivate(int a, int b){
3         return a + b;
4     }
5 }

Mock方法如下:

1 @Test
2 public void testAddPrivate() throws Exception{
3     Calculator calculator = PowerMockito.mock(Calculator.class);
4     PowerMockito.when(calculator, "addPrivate", Mockito.anyInt(), Mockito.anyInt).thenReturn(10);
5 
6     Method method = PowerMockito.method(Calculator.class, "addPrivate", int.class, int.class);
7     int result = (Integer) method.invoke(calculator, 1,1);
8     assertEquals(10, result)
9 }

5. Mock final類或者方法

1 public final class Calculator{
2     public final int add(int a, int b){
3         return a + b;
4     }
5     public final void addVoid(int a, int b){
6         System.out.println(a + b);
7     }
8 }

Mock方法如下:

 1 @RunWith(PowerMockito.class)
 2 @PreparaForTest(Calculator.class)
 3 public class CalculatorTest{
 4     @Test
 5     public void testAdd(){
 6         Calculator calculator PowerMockito.mock(Calculator.class);
 7         PowerMockito.when(calculator.add(Mockito.anyInt(), Mockito.anyInt())).thenReturn(10);
 8         int result = calculator.add(1,1);
 9         assertEquals(result, 10);
10     }
11     @Test
12     public void testAddVoid(){
13         Calculator calculator = PowerMockito.mock(Calculator.class);
14         PowerMockito.doNothing().when(calculator).addVoid(Mockito.anyInt(), Mockito.anyInt());
15         calculator.addVoid(100,100);
16         Mockito.verify(calculator).addVoid(100,100);
17     }
18 }

6. Mock構造函數

類一:

1 public class ClassUnderTest(){
2     public boolean callFinalMethod(){
3         ClassDependency classDependency = new ClassDependency();
4         return classDependency.isAlive();
5     }
6 }

類二:

1 public class ClassDependency{
2     public final boolean isAlive(){
3         return false;
4     }
5 }

Mock方法如下(whenNew創建對象是若不成功(如無對應構造函數))會拋出異常,講義在test塊拋出異常而不是用try。。。catch捕獲,這樣方便問題定位。

@RunWith(PowerMockito.class)
@PreparaForTest({ClassUnderTest.class, ClassDependency.class})
public class TestClassUnderTest{
    @Test
    public void testCallFinalMethod() throws Exception{
        ClassDependency dependency = PowerMockito.mock(ClassDependency.class);
        //該項創建可能會拋出異常
        PowerMockito.whenNew(ClassDependency.class).withNoArguments().thenReturn(dependency);
        ClassUnderTest classUnderTest = new ClassUnderTest();
        Assert.assertEquals(classUnderTest.callFinalMethod());
    }
}

7. 反射設置變量的值

該方法主要是使用WhiteBox的setInternalState方法對變量在某個類中進行替代,模塊中代碼中經常用該方法mock掉數據庫查詢的操作。用本地化的mock數據庫操作(如查詢map對象替代)

public class ReflectObject{
    private String privateStr = "str";
    protected String protectedStr = "str";
    private static String staticStr = "str";

    public String getPrivateStr(){
        return privateStr;
    }

    public String getProtectedStr(){
        return protectedStr;
    }

    public static String getStaticStr(){
        return staticStr;
    }
}

Mock方法如下:

 1 public class ReflectObjectTest(){
 2     @Test
 3     public void testReflect() throws Exception{
 4         ReflectObject reflect = new ReflectObject();
 5         WhiteBox.setInternalState(reflect, "privateStr", "privateStr");
 6         WhiteBox.setInternalState(reflect, "protectedStr", "protectedStr");
 7         WhiteBox.setInternalState(reflect, "staticStr", "staticStr");
 8 
 9         assertEquals("privateStr", reflect.getPrivateStr());
10         assertEquals("protectedStr", reflect.getProtectedStr());
11         assertEquals("staticStr", reflect.getStaticStr());
12     }
13 }

8. Mock靜態方法拋異常

1 public class ThrowsException{
2     public static void throwsException() throws RuntimeException{
3         //do nothing
4     }
5 }

Mock方法如下:

public class ThrowsException{
    @Test(expected=RuntimeException.class)
    public void testThrowsException(){
        PowerMockito.mockStatic(ThrowsException.class);
        PowerMockito.doThrows(new RuntimeException("Test exception")).when(ThrowsException);
        ThrowsException.throwsException();
    }
}

Junit單元測試