2008年4月8日星期二

使用jMock2模拟对象进行单元测试

一、目的

    在OO设计中,经常会出现一个对象拥有另一个对象的情况,而内部对象的行为依赖于容器,不能方便的进行脱离容器的单元测试。为了解决这个问题,就需要将内部对象用其他的对象来代替,使用jMock2来创建模拟对象可以避免在生产代码中创建大量的模拟类(只为了测试而存在),还能保证仿造的接口对象行为的一致性和统一性。

二、需要的jar包

  jmock-2.4.0.jar
  hamcrest-library-1.1.jar
  junit.jar 3.8.2以上,本例使用4.4版本

三、代码
  1. 要测试的类

    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();
        }
    }

  2. 使用的接口

    public interface AnnotationDAO {

        public int getRecordCount();
       
        public void updateEntity(EntityDTO dto);
    }

  3. 单元测试

    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();
        }
    }

没有评论: