junit 加Jmockit单元测试

来源:互联网 发布:win32界面编程 编辑:程序博客网 时间:2024/05/17 07:12

Jmokit
一:环境搭建:
Jar包加载maven:

       <dependency>            <groupId>org.jmockit</groupId>            <artifactId>jmockit</artifactId>            <version>1.18</version>        </dependency>        <dependency>            <groupId>org.jmockit</groupId>            <artifactId>jmockit-coverage</artifactId>            <version>1.18</version>        </dependency>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.8</version>            <scope>test</scope>        </dependency>

gradle :

testCompile("org.jmockit:jmockit:1.30"),

Jmockit.jar包必放在junit.jar包之前,而且junit.jar的版本必须是4.8以上,否则会报错: java.lang.IllegalStateException: JMockit wasn’t properly initialized; check that jmockit.jar precedes junit.jar in the classpath

Mock 简介

Jmockit 整体图

Mock的三个阶段:mock只能mock一次,否则会报错
录制模拟行为:(基于方法返回值)
分为三种:
1:NonStrictExpectations 不限制次数和顺序
2:StrictExpectations 严格限制次数和顺序
3:Expectations 至少调用一次,不要求顺序

new Expectations(Model.class) {         {             Model.getName();             result = "lisi";             Model.getAge();             result = 10;          }};

调用仿制行为
方法的调用
验证调用

        new Verifications() {//验证预期Mock行为被调用                  {                      app.getName();                      times = 1;                     app.getAge();                    times = 1;                }              }; 

Mock两种方式:
(app为对象实例)
@Injectable Model app; //只虚拟app这一个对象
新建其他对象的内容不会改变
@Mocked Model app; //模拟所有的Model类
新建其他对象的内容也将会改变

格式:对象.方法
result = expr //调用这个方法是给他赋予期望值
ps: 当expr 为多个时eg(”a”,”b”,”c”),则按照调用顺序一次给值
第一次:a,第二次:b…
例子:

public void test1(){        //录制mock          new Expectations(app) {              {                  app = new Model();                    app.getName();                  result = "lisi"; //调用getName是赋予“list”                  app.getAge();                  result = 10; //调用getAge是赋予10              }          };//调用mock          assertThat(10, equalTo(app.getAge()));             assertThat("lisi", equalTo(app.getName()));          //校验mock是否被调用并且校验校验调用次数          new Verifications() {//验证预期Mock行为被调用                  {                      app.getName();                      times = 1;                     app.getAge();                    times = 1;                }              };              }

—————————-华丽的分割线———————————
以上都是黑盒测试,不管方法内部,只改变返回值
下面说下改变方法内部的实例(基于方法内部行为)

    new MockUp<Model>() {//使用MockUp修改被测试方法内部逻辑  ,<>中只能为类名            @Mock          public int getAge() {                  return 30;              }          };

用mockUp来对类中的方法内部进行改造
被改造的方法需要用@Mock注解
感觉这个方法是最有用的方法,可以模拟几乎任何行要的方法(包括静态、私有)及返回结果

再举个栗子:*(非接口类型)*    @Tested    //DriverService 是正常类    private DriverService driverService;     @Injectable //这里的driverDAO 是driverService的一个属性,@Injectable可以自动关联,DriverDAO是接口    private DriverDAO driverDAO;    @Test    public void testFind() {        //正常类        new MockUp<DriverService>() {         @Mock         public Driver findDriver(String Id){                return  new Driver(){{setTimestamp(new DateTime());}};            }        };        //接口类         driverDAO = new MockUp<DriverDAO>() {            @Mock            public Driver findOne(String Id){                return  new Driver(){{setUuid("44444444");}};            }        }.getMockInstance();//需要获取实例        Driver driver = driverService.findDriver("");        Driver Driver = driverDAO.findOne("");        System.out.println(driver);    }

下面再说下Jmockit提供的一些工具API
虚拟构造方法:

public void test6(@Mocked Model app){        new Expectations() {              {                  new Model();                  result = app;                  app.getAge();                  result = 111;                  app.getPName();                  result = "lisi";              }         };         System.out.println(new Model().getAge());         System.out.println(new Model().getPName());    }

虚拟私有方法:

new Expectations(app) {              {                  Deencapsulation.invoke(app, "getName");                  result = "lisi";              }assertThat("lisi", equalTo(app.getPName()));

虚拟静态方法:

new Expectations(Model.class) {              {                  Deencapsulation.invoke(Model.class, "getName");                  result = "lisi";              }          };assertThat("lisi", equalTo(Model.getPName()));

用Delegate类返回值

new Expectations(app) {              {                  app.getAge();                  result = new Delegate(){                      int aaa(){                          return 1;                      }                  };              }};

注:里面的实现方法名称可以任意,但只能存在一个方法,且不能为私有

一些关键字
对模拟调用次数限制:times = ? 次数
minTimes = ? 最小
maxTime = ? 最大
minTime = ? ;maxTime = ? 在之间
anyString 等 any…系列字段:表示任何这种类型

0 0
原创粉丝点击