junit 加Jmockit单元测试

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

       <dependency>
            <groupId>org.jmockitgroupId>
            <artifactId>jmockitartifactId>
            <version>1.18version>
        dependency>
        <dependency>
            <groupId>org.jmockitgroupId>
            <artifactId>jmockit-coverageartifactId>
            <version>1.18version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.8version>
            <scope>testscope>
        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() {//使用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() {
         @Mock
         public Driver findDriver(String Id){
                return  new Driver(){{setTimestamp(new DateTime());}};
            }
        };
        //接口类
         driverDAO = new MockUp() {
            @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…系列字段:表示任何这种类型

你可能感兴趣的:(学习笔记)