EasyMock 使用点滴

稍稍记录一下EasyMock的使用。

废话没有,单元测试一般都会用XUnit测试框架。简单对象或方法还好,倘若出现复杂对象依赖那么光是准备依赖对象就够喝一壶的了。譬如要测试
Class_A.method(Class_B obj){...}
Class_B depends Class_C.

Mock对象便出马了,其实就是基于动态代理机制产生Class_B/Class_C的实例。听说过JMock,EasyMock,MockEJB等等,目前尝试过的只有EasyMock.下面开始。

从EasyMock站点下载发行包,我使用的是easymock-2.5.2。使用很简单,查看user guide就可以上手了。

EasyMock默认只能创建基于Interface的mock对象,如
EasyMock.createMock(DataManagerInterface.class);
.若要能够mock具类,则要使用扩展包 classextension,如
org.easymock.classextension.EasyMock.createMock(DataManagerConcret.class)

一点提示,使用classextension时还需要下载objenesis-1.2.jar,文档里面没有提到不过网上有的下。在我看来,具类测试使用比较频繁。

创建完之后,则是设定mock对象的状态。EasyMock将mock对象分为录制,回放(replay)两个阶段。刚开写的时候,以为poConsumption1里面的属性还需要自己创建,
poConsumption1.setId(dbId1)
poConsumption1.setCategoryrow(Category1)
poConsumption1.setName(rowName1)
poConsumption1.setPrice(rowPrice1)

其实下面才是mock对象能够设定的属性,
//create mock object
POConsumption poConsumption1 = EasyMock.createMock(POConsumption.class);
// record invocation state
EasyMock.expect(poConsumption1.getId()).andReturn(dbId1);//expect getId return dbId1	
EasyMock.expect(poConsumption1.getCategory()).andReturn(rowCategory1);
EasyMock.expect(poConsumption1.getName()).andReturn(rowName1);
EasyMock.expect(poConsumption1.getPrice()).andReturn(rowPrice1);

接着便是回放阶段,
		// switch to the replay state
		EasyMock.replay(poConsumption1);

调用业务逻辑,
// put them into the list
List<POConsumption> list = new ArrayList<POConsumption>();
list.add(poConsumption1);
// call business function
RowData[] rowDataAray = utility.convertToRowDataArray(list);
// assumption
assertEquals(list.size(), rowDataAray.length);


如果convertToRowDataArray()里面调用到了POConsuumption的其他方法,那么将会throw exception:Unexpected method invocation,因为这个方法不是预期调用的(没有录制)。

如果在最后加上
EasyMock.verify(poConsumption1);

则意味着录制的所有方法都必须被convertToRowDataArray()调用到,否则fail.

真是够简单。IBM developerWorks上有一篇很好的 文章关于EasyMock框架的原理和使用,so far so good.

顺便提及dao的测试,我本人觉得没有必要,CRUD有必要费老大劲来单元测试吗?去mock数据存储?如果架构合理,高度模块化,复杂的业务逻辑测试才是mock对象用武之地。

你可能感兴趣的:(java,DAO,IBM,单元测试,OpenSource)