最近在研究提高代码的可测性,使项目能更好完成,以下就是本人使用EasyMock的测试小例子
对于EasyMock的测试是基于 期望+实测 的比对
一般的一个测试单元如下
1:记录测试中使用到的方法与返回值
2:设置对象到回放模式
3:进行测试
4:验证操作
基于大家对Junit的熟悉,具体我就不说了,可以参考TestCase的有关API
下面以自己编写的具体例子说明
1:一个IStudent接口
2:具体的实现类Student
3: 具体调用的学校类 School,此处仅实现简单的方法
好,现在可以开始测试了,针对IStudent接口的测试
4a: IStudentTest.java 需继承父类TestCase
接下来是对Student类的测试
4b: 除了修改引入包和控制的生成,其他代码无需修改
好了,代码里有很多注释,基本原理可以google一下,可以找到很多资料
对于EasyMock的测试是基于 期望+实测 的比对
一般的一个测试单元如下
1:记录测试中使用到的方法与返回值
//
期望发生一次documentAdded("Document 1")的调用
mock.documentAdded( " Document 1 " );
mock.documentAdded( " Document 1 " );
2:设置对象到回放模式
replay(mock);
//
回放
3:进行测试
classUnderTest.addDocument(
"
Document 1
"
,
new
byte
[
0
]);
4:验证操作
/*
* 验证调用
*/
verify(mock);
* 验证调用
*/
verify(mock);
基于大家对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();
}
* 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;
}
}
* 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();
}
}
* 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);
}
}
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);
}
}
/*
* 引入扩展类包
*/
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一下,可以找到很多资料