在OO设计中,经常会出现一个对象拥有另一个对象的情况,而内部对象的行为依赖于容器,不能方便的进行脱离容器的单元测试。为了解决这个问题,就需要将内部对象用其他的对象来代替,使用jMock2来创建模拟对象可以避免在生产代码中创建大量的模拟类(只为了测试而存在),还能保证仿造的接口对象行为的一致性和统一性。
二、需要的jar包
jmock-2.4.0.jar
hamcrest-library-1.1.jar
junit.jar 3.8.2以上,本例使用4.4版本
三、代码
- 要测试的类
public class DAOService {
private AnnotationDAO dao;
public DAOService() {
}
public DAOService(AnnotationDAO dao) {
this.dao = dao;
}
public void updateEntity(EntityDTO dto) {
dao.updateEntity(dto);
}
public int getRecordCount() {
return dao.getRecordCount();
}
}
- 使用的接口
public interface AnnotationDAO {
public int getRecordCount();
public void updateEntity(EntityDTO dto);
}
- 单元测试
public class DAOServiceMockTest {
private Mockery mocker;
private AnnotationDAO dao; //mock对象
private DAOService service;
public DAOServiceMockTest() {
}
@Before
public void setUp() {
mocker = new Mockery();
dao = mocker.mock(AnnotationDAO.class); //创建mock对象,注意AnnotationDAO是一个接口
service = new DAOService(dao); //用创建的mock对象实例创建测试对象
}
@After
public void tearDown() {
}
@Test
public void testUpdateEntity() {
final EntityDTO dto = new EntityDTO("1", "Tom", "Sawyer");
mocker.checking(new Expectations() {{ //定义预期
one (dao).updateEntity(dto); //one表示此mock对象方法只执行一次,void类型无返回值,注意可以传入参数
}});
service.updateEntity(dto);
mocker.assertIsSatisfied(); //将执行结果与预期比较
}
@Test
public void testGetRecordCount(){
mocker.checking(new Expectations() {{
one (dao).getRecordCount();
will(returnValue(15)); //执行此方法将返回整数15,returnValue参数值是一个对象,如果返回集合或抛出异常使用其他方法
}});
assertEquals(15, service.getRecordCount());
mocker.assertIsSatisfied();
}
}