最近在研究提高代码的可测性,使项目能更好完成,以下就是本人使用EasyMock的测试小例子
对于EasyMock的测试是基于 期望+实测 的比对
一般的一个测试单元如下
1:记录测试中使用到的方法与返回值
//
期望发生一次documentAdded("Document 1")的调用
mock.documentAdded(
"
Document 1
"
);
2:设置对象到回放模式
replay(mock);
//
回放
3:进行测试
classUnderTest.addDocument(
"
Document 1
"
,
new
byte
[
0
]);
4:验证操作
基于大家对Junit的熟悉,具体我就不说了,可以参考TestCase的有关API
下面以自己编写的具体例子说明
1:一个IStudent接口
/**
* IStudent.java 2006-9-15
*/
package
person.fane.example.easymock;

/**
* 学生接口
* @author Fane
* @version 1.0.0.0
*/
public
interface
IStudent
{
/**
* 获取学生的名字
* @return String
*/
String getName();
/**
* 设置学生的名字
* @param name
*/
void setName(String name);
/**
* 获取学生的年龄
* @return int
*/
int getAge();
/**
* 设置学生的年龄
* @param age
*/
void setAge(int age);
/**
* 判断是否满18岁
* @return boolean
*/
boolean isOlderThan18();

}
2:具体的实现类Student
/**
* Student.java 2006-9-15
*/
package
person.fane.example.easymock;

/**
* 学生接口实现类
* @author Fane
* @version 1.0.0.0
*/
public
class
Student
implements
IStudent
{

/*
* 学生属性
*/
private String name = "";
private int age = 1;
/* (non-Javadoc)
* @see person.fane.example.easymock.IStudent#getName()
*/
public String getName() {
return name;
}

/* (non-Javadoc)
* @see person.fane.example.easymock.IStudent#setName(java.lang.String)
*/
public void setName(String name) {
this.name = name;
}

/* (non-Javadoc)
* @see person.fane.example.easymock.IStudent#getAge()
*/
public int getAge() {
return age;
}

/* (non-Javadoc)
* @see person.fane.example.easymock.IStudent#setAge(int)
*/
public void setAge(int age) {
this.age = age;
}

/* (non-Javadoc)
* @see person.fane.example.easymock.IStudent#isOlderThan18(person.fane.example.easymock.IStudent)
*/
public boolean isOlderThan18() {
return this.getAge() > 18;
}

}
3: 具体调用的学校类 School,此处仅实现简单的方法
/**
* School.java 2006-9-15
*/
package
person.fane.example.easymock;


/**
* 学校类
* @author Fane
* @version 1.0.0.0
*/
public
class
School
{

/*
* 学校的学生成员,此出作测试,故没有写成一个集合,就当这个学校只有一个学生
*/
private IStudent student;
/**
* 设置学校的学生对象
* @param student
*/
public School(IStudent student)
{
this.student = student;
}
/**
* 设置学校学生的名字
* @param name
*/
public void setStudentName(String name)
{
this.student.setName(name);
}
/**
* 获取学校学生的名字
* @return String
*/
public String getStudentName()
{
return this.student.getName();
}
/**
* 设置学校学生的年龄
* @param age
*/
public void setStudentAge(int age)
{
this.student.setAge(age);
}
/**
* 获取学校的学生的年龄
* @return int
*/
public int getStudentAge()
{
return this.student.getAge();
}
/**
* 判断该学校该名学生的年龄是否大于18
* @return
*/
public boolean isStudentOlderThan18()
{
return this.student.isOlderThan18();
}
}
好,现在可以开始测试了,针对IStudent接口的测试
4a: IStudentTest.java 需继承父类TestCase
package
person.fane.example.easymock;

import
static
org.easymock.EasyMock.
*
;

import
junit.framework.TestCase;

public
class
IStudentTest
extends
TestCase
{

/*
* 具体调用的学校类
*/
private School newSchool;
/*
* 被作为测试的控制对象
*/
private IStudent mock;
/**
* 完成必要的初始化工作
*/
protected void setUp() throws Exception {
super.setUp();
/*
* 创建控制对象
*/
mock = createMock(IStudent.class);
/*
* 将控制对象传递到调用类中,
* 如此单该类调用方法时,就会使用控制对象的方法
*/
newSchool = new School(mock);
}

/*
* Test method for 'person.fane.example.easymock.IStudent.getName()'
*/
public void testGetName() {
expect(mock.getName()).andReturn("Fane");
replay(mock);
newSchool.getStudentName();
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.IStudent.setName(String)'
*/
public void testSetName() {
mock.setName("Fane");
replay(mock);
newSchool.setStudentName("Fane");
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.IStudent.getAge()'
*/
public void testGetAge() {
expect(mock.getAge()).andReturn(12);
replay(mock);
newSchool.getStudentAge();
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.IStudent.setAge(int)'
*/
public void testSetAge() {
mock.setAge(12);
replay(mock);
newSchool.setStudentAge(12);
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.IStudent.isOlderThan18(IStudent)'
*/
public void testIsOlderThan18() {
expect(mock.isOlderThan18()).andReturn(false);
replay(mock);
newSchool.isStudentOlderThan18();
verify(mock);
}

}
接下来是对Student类的测试
4b: 除了修改引入包和控制的生成,其他代码无需修改
package
person.fane.example.easymock;
/*
* 引入扩展类包
*/
import
static
org.easymock.classextension.EasyMock.
*
;

import
junit.framework.TestCase;

public
class
StudentTest
extends
TestCase
{

private School newSchool;
private Student mock;
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
mock = createMock(Student.class); //修改为类
newSchool = new School(mock);
}

/*
* Test method for 'person.fane.example.easymock.Student.getName()'
*/
public void testGetName() {
expect(mock.getName()).andReturn("Fane"); //如果遇到getName()方法调用,则返回"Fane"
replay(mock);
String name = newSchool.getStudentName();
assertEquals("Fane",name); //验证是否返回"Fane"
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.Student.setName(String)'
*/
public void testSetName() {
mock.setName("Fane");
replay(mock);
newSchool.setStudentName("Fane");
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.Student.getAge()'
*/
public void testGetAge() {
expect(mock.getAge()).andReturn(12);
replay(mock);
newSchool.getStudentAge();
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.Student.setAge(int)'
*/
public void testSetAge() {
mock.setAge(12);
replay(mock);
newSchool.setStudentAge(12);
verify(mock);
}

/*
* Test method for 'person.fane.example.easymock.Student.isOlderThan18()'
*/
public void testIsOlderThan18() {
expect(mock.isOlderThan18()).andReturn(false);
replay(mock);
newSchool.isStudentOlderThan18();
verify(mock);
}

}
好了,代码里有很多注释,基本原理可以google一下,可以找到很多资料
对于EasyMock的测试是基于 期望+实测 的比对
一般的一个测试单元如下
1:记录测试中使用到的方法与返回值


2:设置对象到回放模式

3:进行测试

4:验证操作
/*
* 验证调用
*/
verify(mock);
* 验证调用
*/
verify(mock);
基于大家对Junit的熟悉,具体我就不说了,可以参考TestCase的有关API
下面以自己编写的具体例子说明
1:一个IStudent接口








































2:具体的实现类Student
























































3: 具体调用的学校类 School,此处仅实现简单的方法







































































好,现在可以开始测试了,针对IStudent接口的测试
4a: IStudentTest.java 需继承父类TestCase


























































































接下来是对Student类的测试
4b: 除了修改引入包和控制的生成,其他代码无需修改

















































































好了,代码里有很多注释,基本原理可以google一下,可以找到很多资料