zoukankan      html  css  js  c++  java
  • 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();
        }
    }
  • 相关阅读:
    Html学习_简易个人网页制作
    Html学习_style属性应用
    xode9.0的xcodebuild -exportArchive -archivePath 导出ipa包报错Error Domain=IDEProvisioningErrorDomain Code=3
    xcode8,Application Loader上传ipa包iTunes connect不显示构建版本问题
    git统计代码总行数
    Gerri review 代码管理规范
    ! [remote rejected] HEAD -> refs/for/ToonV3.0 (missing Change-Id in commit message footer)
    git分支管理和冲突
    Gerrit出现 Submitted, Merge Pending 和 Merge Conflict
    Git命令大全
  • 原文地址:https://www.cnblogs.com/sxmcACM/p/8167662.html
Copyright © 2011-2022 走看看