Junit单元测试

Posted Dream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Junit单元测试相关的知识,希望对你有一定的参考价值。

      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单元测试的主要内容,如果未能解决你的问题,请参考以下文章

四则运算单元测试

JUnit单元测试

通过JUnit进行Android单元测试

JUnit单元测试

JUnit单元测试

Junit单元测试--01