浅谈Jmockit使用

原创 2015年07月08日 13:52:20

  最近公司里要求使用Jmockit来辅助单元测试。之前也没接触过,研究了几天,今天就跟大家谈谈我怎么使用Jmockit。写一个小例子供大家参考。

  如有不对的地方还请大家多多指正

  对于Mock的作用这里就不详细介绍了,不清楚的可以自行百度。笔者使用的是1.15版本的Jmockit(默认读者已经把相应的包导好)

  在开始测试之前我们先写一个简单的Java类,代码如下

 

public class GetServiceForBook {


  public int getService(String bookType) {

    if ("novel".equals(bookType)){
      return 1;
    }
    else {
      return 2;
    }
  }
}

  以上是一个极其简单的一个Java类,里面定义了一个getService方法。看了这个方法后可以确定,调用这个方法后得到的结果不是1就2.下面我们就来写一个小单元测试。

import static org.junit.Assert.*;
import org.junit.Test;

public class GetServiceForBookTest {
  
  private GetServiceForBook getServiceForBook = new GetServiceForBook();
  
  @Test
  public void testBookService() {
      
   int test = getServiceForBook.getService("novel");
    
   assertEquals(1,test);
 }
}

  对于上面的单元测试我相信不会有人看不懂,而且简单运行一下就是一个长长的绿条。那下面我们就开始使用Mock来“修改”我们的GetServiceForBook类。

  刚刚也说明了,对于getService方法的返回值不是1就是2。那如果我想让getService返回3怎么办?很简单,使用Mock。先上Expectations的方式。

import static org.junit.Assert.*;
import mockit.Expectations;
import mockit.Injectable;

import org.junit.Test;

public class GetServiceForBookTest {
  
  @Injectable
  private GetServiceForBook getServiceForBook;
  
  @Test
  public void testBookService() {
      
   new Expectations(){
     {
       getServiceForBook.getService(anyString);
       result = 3;
       times = 1;
     }
     
   };
    
   int test = getServiceForBook.getService("novel");
   assertEquals(3,test);
 }
}
  以上就是使用Mock的方式把getService方法给“修改”了。所以底下的断言是看test和3的比较。很明显,这里用了Expectations把getService的返回值改成了3,也就是说在这个测试里不论我传进去的参数是什么,它的返回都是3.(使用@Injectable系统会自动注入,创建实例。)下面在给一个使用MockUp方式

import static org.junit.Assert.*;
import mockit.Mock;
import mockit.MockUp;

import org.junit.Test;

public class GetServiceForBookTest {
  

  private GetServiceForBook getServiceForBook = new GetServiceForBook();
  
  @Test
  public void testBookService() {
    
   new MockUp<GetServiceForBook>(){
     @Mock
     public int getService(String bookType)
     {
       return 3;
     }
   };
    
   int test = getServiceForBook.getService("novel");
   assertEquals(3,test);
 }
}
  可以看出这两个Mock的结果是一样的都是把getService的方法改成3. 但是MockUp方式跟Expectations不同的是,MockUp把getService方法重新写了一遍并不像Expectations那样只要设定下变量就可以改变getService方法。


  现在,我们稍微修改下原来的GetServiceForBook类。

package cn.com.liandisys.book.service;

public class GetServiceForBook {


  JustForTest jft = new JustForTest();

  public GetServiceForBook()
  {

  }

  public GetServiceForBook(JustForTest jft)
  {
    this.jft = jft;
  }

  public int getService(String bookType) {

    boolean flag = jft.getResult();
    System.out.println(flag);
    if ("novel".equals(bookType)) {
      return 1;
    }
    else {
      return 2;
    }
  }
}

  看到里面多了一个JustForTest的类,下面把JustForTest类代码贴出来

public class JustForTest {

  public boolean getResult() {
    return false;
  }

}
依然是一个简单的Java类,我们可以看出这个JustForTest类里有一个getResult的方法,这个方法返回的永远是false. 在GetServiceForBook类里申明了一个JustForTest类并调用了getResult方法然后打印出来。不出意外这个输出结果应该永远都是false。那下面我们用Mock把getResult方法“修改”成true。

import static org.junit.Assert.*;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Tested;

import org.junit.Test;

public class GetServiceForBookTest {
  
  @Tested
  private GetServiceForBook getServiceForBook;
  
  @Injectable
  private JustForTest jft;
  
  @Test
  public void testBookService() {
    
   new Expectations(){
     
     {
        jft.getResult();
        result = true;
        times = 1;
     }
     
   };
    
   int test = getServiceForBook.getService("novel");
   assertEquals(1,test);
 }
}

  由于我们并没有mock掉getService所以返回值不是1就是2,对于上面的单元测试,给的参数是novel那返回值就应该是1。 然后我们运行一下可以发现控制台输出的是true而不是false了,这是因为我们把JustForTest类的getResult方法给Mock掉了。

  里面还有两个注解一个@Tested一个是@Injectable。第一个@Tested不能变只能是这个,第二个可以写成@Mocked。如果第一个改成@Mocked的话输出结果就变成0,也就是说不过你的参数是什么结果都是输出0。这是因为在你使用Mocked注解时,如果没有进行“修改”,那系统就会自己帮你把这个类里的所有方法都Mock掉,而mock的内容就是返回默认值。(int的默认值是0)。

 下面给出使用MockUp方式的

import static org.junit.Assert.*;
import mockit.Mock;
import mockit.MockUp;

import org.junit.Test;

public class GetServiceForBookTest {
  
  private GetServiceForBook getServiceForBook = new GetServiceForBook();
  
  @Test
  public void testBookService() {
    
    new MockUp<JustForTest>(){
      @Mock
      public boolean getResult()
      {
        return true;
      }
    };
    
    int test = getServiceForBook.getService("novel");
    assertEquals(1,test);
 }
}
  这里就不多解释了,跟上面的MockUp例子很像,同样也是把getResult输出true。

  通过查阅Jmockit文档,发现MockUp有一个方法叫getMockInstance。也就是创建一个Mock实例。我们可以这样理解,每一个需要被Mock的代码都可以看作是一个对象。就拿上面getResult例子来说JustForTest可以把它看作是一个Mock对象。所以我们还可以改成下面的形式。

import static org.junit.Assert.*;
import mockit.Mock;
import mockit.MockUp;

import org.junit.Test;

public class GetServiceForBookTest {
  
  private GetServiceForBook getServiceForBook;
  
  @Test
  public void testBookService() {
    
    JustForTest mock = new MockUp<JustForTest>(){
      @Mock
      public boolean getResult()
      {
        return true;
      }
    }.getMockInstance();
    
    getServiceForBook = new GetServiceForBook(mock);
    int test = getServiceForBook.getService("novel");
    assertEquals(1,test);
 }
}
  这就是为什么我去重写getServiceForBook的构造函数,把Mock创建出来的对象赋给getServiceForBook里的JustForTest,这样也能达到Mock的目的


  这次就先写到这里,其实对于Jmockit来说,这个只是沧海一栗,里面还有多东西需要研究,这里就先跟大家分享这么多,希望能对读者有用。

 这是我第一次写博客,可能还有很多不足的地方,还请大大多多指教。

JMockit Mock测试入门详解

JMockit Mock测试入门详解,简单介绍了JMockit的使用方法
  • zhglance
  • zhglance
  • 2016年09月02日 20:33
  • 492

JMockit学习之mock接口和抽象类

大型软件项目,往往会在设计的时候进行模块化划分,模块之间存在依赖关系。为了减少各个模块之间的耦合,通过接口进行依赖,各个模块由不同的开发组进行并行开发。如果A模块需要使用B模块的接口,但是B模块由于开...
  • aitangyong
  • aitangyong
  • 2014年02月27日 19:09
  • 7367

使用 JMockit 来 mock 构造函数

Java 测试的 Mock 框架以前是用 JMockit, 最近用了一段时间的 Mockito, 除了它流畅的书写方式,经常这也 Mock 不了,那也 Mock 不了,需要迁就于测试来调整实现代码,使...
  • kypfos
  • kypfos
  • 2017年04月14日 23:40
  • 1391

Jmockit使用指南

概述 mock对象 这个虚拟的对象就是mock对象。mock对象就是真实对象在调试期间的代替品。...
  • y461517142
  • y461517142
  • 2014年05月27日 20:20
  • 7047

Java 各种Mock工具比较

转自: http://billben.iteye.com/blog/1872196 http://harrywu304.blog.163.com/blog/static/84566032011...
  • yasi_xi
  • yasi_xi
  • 2014年04月28日 14:56
  • 16268

单元测试mock框架——jmockit实战

JMockit是google code上面的一个java单元测试mock项目,她很方便地让你对单元测试中的final类,静态方法,构造方法进行mock,功能强大。项目地址在:http://jmocki...
  • UltraNi
  • UltraNi
  • 2013年05月30日 20:18
  • 43039

JMockit简单使用

JMockit是google code上面的一个java单元测试的mock框架。 JMockit涉及到的元素介绍: @Tested和@Injectable      对@Tested对象判断是否...
  • zero__007
  • zero__007
  • 2015年10月20日 18:22
  • 4227

JMockit的主要注解

1、@Mocked,标识一个指定的class的实例或被测对象的参数被Mock掉。         除了基本类型和Array,其他所有类型都可以通过@Mocked标识来被Mock掉。当一个被测对象的参...
  • zzpzheng
  • zzpzheng
  • 2016年07月31日 21:53
  • 1452

使用JMockit编写java单元测试

之前《有效使用Mock编写java单元测试》一文中层介绍过使用EasyMock和PowerMock来编写java单元测试,今天介绍一个更加强大的工具——JMockit。 引用单元测试中mock的使用...
  • chjttony
  • chjttony
  • 2014年01月04日 10:55
  • 27241

JMockit学习笔记

基本概念常用注解 @Mocked:被修饰的对象将会被Mock,对应的类和实例都会受影响(同一个测试用例中) @Injectable:仅Mock被修饰的对象 @Capturing:可以mock接口以及其...
  • u011331383
  • u011331383
  • 2016年04月24日 17:18
  • 2803
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:浅谈Jmockit使用
举报原因:
原因补充:

(最多只允许输入30个字)