EasyMock基本使用

EasyMock 
同时可以参看:EasyMock 使用方法与原理剖析

或者:http://webcache.googleusercontent.com/search?q=cache:FeHb5AoQOtcJ:www.ibm.com/developerworks/cn/opensource/os-cn-easymock/+EasyMock+使用方法与原理剖析&cd=1&hl=zh-CN&ct=clnk

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.     } 

 

 

 

 

你可能感兴趣的:(职场,easymock,休闲)