EasyMock基本使用

简介:

我们的第一个例子非常简单,但是在现实情况下,你通常是在一些类里使用另外的一些类。在进行真正的测试之前,你可能需要做很多的工作,比喻说安置大量的环境代码,启动一种大型的、复杂的系统,可能是数据库、工作流或者是某一种类型的IDE环境,你的预设环境代码需要是系统进入某种特定的状态,以便按照测试所需要的方法进行响应。但是这种工作不大可能很快就能完成。

  为了对一部分类进行单元测试,你需要建立和控制另外一些类。最好的办法就是为需要测试的类创建一个模拟对象。你可以自己手工的编写类,也可以使用EasyMock来产生这些对象。模拟对象提供了一种经过证明是成功的解决方案。

  当我们很难或不可能为某种难以处理的资源创建需要的状态或者存取某种资源受限时,你就可以使用模拟对象

  模拟对象取代真实对象的位置,用于测试一些与真实对象进行交互或依赖于真实对象的功能。模拟对象背后的基本思想就是创建轻量级的、可控制的对象来代替为了编写测试为需要使用的对象。模拟对象还能够让你指定和测试你的代码与模拟对象本身之间的交互。

说的再直白一点,一个模拟对象就是一个简单的接口或者是类,在里面你可以定义一个特定的方法调用之后的简单的输出。

 

使用JunitEasy Mock

EasyMock到主页上下载EasyMock, 把下载得到的easymock.jar增加到你的classpath中。

创建一个Java工程JavaMockTest,创建下面的这些类。

IncomeCalculator是要被测试的类,这个类用来根据一个人的职位来计算一个人的工资的方法。 

 

package income;

public  enum Position {BOSS, PROGRAMMER, SURFER} 

package income.exceptions;

public  class PositionException  extends RuntimeException {

private  static  final  long serialVersionUID = 1L;

public PositionException(String message) {

super(message);



package income.exceptions;

public  class CalcMethodException  extends RuntimeException {

private  static  final  long serialVersionUID = 1L;

public CalcMethodException(String message) {

super(message);


package income.method;

import income.Position;

public  interface ICalcMethod {

public  abstract  double calc(Position position);

}

package income;

import income.exceptions.CalcMethodException;

import income.exceptions.PositionException;

import income.method.ICalcMethod;

public  class IncomeCalculator{

private ICalcMethod calcMethod;

private Position position;

public  void setCalcMethod(ICalcMethod calcMethod){

this.calcMethod = calcMethod;

}
public  void setPosition(Position position){

this.position = position;


public  double calc (){

if (calcMethod== null){

throw  new CalcMethodException( "CalcMethod not yet maintained");

}

if (position== null){

throw  new PositionException( "Position not yet maintained");

}

return calcMethod.calc(position);

}

 

使用EclipseJUnit功能为IncomeCalulator创建一个测试。在我的例子中,我同时创建一个新的源文件夹,名字为"test",我把我创建的测试类全部放到里面。

 下面就是一个使用EasyMock创建的测试。 

 

package income;

import  static org.junit.Assert.assertEquals;

import  static org.junit.Assert.fail;

import income.exceptions.CalcMethodException;

import income.exceptions.PositionException;

import income.method.ICalcMethod;

import org.easymock.EasyMock;

import org.junit.Before;

import org.junit.Test; 

public  class IncomeCalculatorTest { 

private ICalcMethod calcMethod;

private IncomeCalculator calc; 

@Before

public  void setUp()  throws Exception {

calcMethod = EasyMock.createMock(ICalcMethod. class);

calc =  new IncomeCalculator();

}

@Test

public  void testCalc1() {

// Setting up the expected value of the method call calc

EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0).times(2);

EasyMock.expect(calcMethod.calc(Position.PROGRAMMER)).andReturn(50000.0);

// Setup is finished need to activate the mock

EasyMock.replay(calcMethod); 

calc.setCalcMethod(calcMethod);

try {

calc.calc();

fail( "Exception did not occur");

catch (PositionException e) {

}

calc.setPosition(Position.BOSS);

assertEquals(70000.0, calc.calc());

assertEquals(70000.0, calc.calc());

calc.setPosition(Position.PROGRAMMER);

assertEquals(50000.0, calc.calc());

calc.setPosition(Position.SURFER);

EasyMock.verify(calcMethod);

}

@Test(expected = CalcMethodException. class)

public  void testNoCalc() {

calc.setPosition(Position.SURFER);

calc.calc();

}

@Test(expected = PositionException. class)

public  void testNoPosition() {

EasyMock.expect(calcMethod.calc(Position.BOSS)).andReturn(70000.0);

EasyMock.replay(calcMethod);

calc.setCalcMethod(calcMethod);

calc.calc();

}

@Test(expected = PositionException. class)

public  void testCalc2() {

// Setting up the expected value of the method call calc

EasyMock.expect(calcMethod.calc(Position.SURFER)).andThrow( new PositionException( "Don't know this guy")).times(1); 

// Setup is finished need to activate the mock

EasyMock.replay(calcMethod);

calc.setPosition(Position.SURFER);

calc.setCalcMethod(calcMethod);

calc.calc();

}

 

 

 

 

 

 

 

  expect方法告知EasyMock希望得到一个特定的方法,使用一些特定的参数,addReturn为某一个方法定义返回值。times方法定义了模拟对象将被调用几次。 reply方法需要在让模拟对象可用之前被调用。执行完测试之后,你可以调用verify方法来检查模拟对象是不是跟预期的一样被调用了。

 

1、mock次数的设置

times(int count):
要以范围的方式定义调用次数,能够使用其他方法代替 times(int count)
times(int min, int max)
to  expect between  min  and  max  calls,
用上下限指定方法调用次数。
atLeastOnce ()
to  expect at least one call, and
指定该方法至少被调用一次。
anyTimes ()
to  expected an unrestricted number of calls.
不限制对该方法的调用。

 

2、接口、抽象类、类的mock

org.easymock.classextension.EasyMock 被用来mock抽象类(abstract)和具体类 

org.easymock.EasyMock被用来mock接口(interface) 

3、创建多个 Mock 对象,EasyMock 提供了另外一种生成和管理 Mock 对象的机制

IMocksControl control = EasyMock.createControl();
java.sql.Connection mockConnection = control.createMock(Connection.class);
java.sql.Statement mockStatement = control.createMock(Statement.class);
java.sql.ResultSet mockResultSet = control.createMock(ResultSet.class);

 4、多个接口进行mock, 且之间存在相互关系, 例子如下:

 
  1. @Test 
  2.     public void testMock() throws Exception{ 
  3.         Connection conn = EasyMock.createMock(Connection.class); 
  4.         PreparedStatement ps = EasyMock.createMock(PreparedStatement.class); 
  5.         ResultSet rs = EasyMock.createMock(ResultSet.class); 
  6.          
  7.         EasyMock.expect(conn.prepareStatement("")).andReturn(ps).anyTimes(); 
  8.         EasyMock.expect(ps.executeQuery()).andReturn(rs).anyTimes(); 
  9.         EasyMock.expect(rs.getFloat(1)).andReturn(10.0f).anyTimes(); 
  10.          
  11.         EasyMock.replay(conn); 
  12.         EasyMock.replay(ps); 
  13.         EasyMock.replay(rs); 
  14.          
  15.         System.out.println(conn.prepareStatement("").executeQuery().getFloat(1)); 
  16.     } 

 

 

 本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/268397,如需转载请自行联系原作者

相关文章
|
18天前
最新jsonwebtoken-jjwt 0.12.3 基本使用
最新jsonwebtoken-jjwt 0.12.3 基本使用
59 0
|
4月前
|
存储 缓存 Java
【scoop】安装及基本使用
【scoop】安装及基本使用
209 0
|
5月前
|
存储 NoSQL 定位技术
RedisGEO的基本使用
对GEO的基本介绍
CodeBlock 基本使用
基本介绍 代码块又称为初始化块,属于类中的成员【即是类的一部分,类似于方法,讲逻辑语句封装在方法体中,通过{}包围起来】 和方法不同,没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时或创建对象时隐式调用。
98 0
|
Go
基本使用
基本使用
63 0
|
机器人 测试技术 Android开发
【第二篇】XiaoZaiMultiAutoAiDevices之基本使用
从一个框架,延伸各项知识点,补补基础,挺好~
117 0
|
缓存 Shell 索引
ElastchSearch 基本使用姿势
ElastchSearch 基本使用姿势,如常见的 添加文档 常见的查询姿势 修改/删除文档
234 0
ElastchSearch 基本使用姿势
|
定位技术
MapKit的基本使用
MapKit的基本使用
466 0
MapKit的基本使用
|
Web App开发 存储 监控
【ChromeDevTool】Performace的简单使用
【ChromeDevTool】Performace的简单使用
【ChromeDevTool】Performace的简单使用