使用场景:对于调用其它类中的方法,但是还没有编写完,使用easymock进行单元测试,它提供这些没有编写完的代码期待的默认值。
使用步骤:
step1:
pom引入:
1 <dependency> 2 <groupId>org.easymock</groupId> 3 <artifactId>easymock</artifactId> 4 <version>3.2</version> 5 </dependency> 6 <dependency> 7 <groupId>org.easymock</groupId> 8 <artifactId>easymockclassextension</artifactId> 9 <version>3.2</version> 10 </dependency> 11 <dependency> 12 <groupId>org.easymock</groupId> 13 <artifactId>com.springsource.easymockclassextension</artifactId> 14 <version>3.2</version> 15 </dependency>
2、使用easymock中的方法编写单元测试
第一,创建mocks的类
需要注意的是:一般使用EasyMock.createMock创建mock对象,但是一些对象需要set一些值,这时候我们可以使用EasyMock.createNiceMock
第二,开始录制
第三,mock回放
需要注意的是:只能回放用mock创建的对象,比如new出来的对象就不能回放;
第四,使用
测试单元:
1 /** 2 * 使用easymock测试GetTotalAmount 3 * @throws ParseException 4 */ 5 @Test 6 public void testGetTotalAmount() throws ParseException { 7 Reconciliation reconciliation = EasyMock 8 .createMock(Reconciliation.class); 9 Date endTime = new Date(); 10 Date startTime = new Date(); 11 12 Calendar calendar = Calendar.getInstance(); 13 calendar.setTime(endTime); 14 calendar.add(Calendar.DATE, -1); 15 startTime = calendar.getTime(); 16 EasyMock.expect(reconciliation.getReconciliationStartTime()) 17 .andReturn(startTime); 18 // TODO 1 19 EasyMock.expectLastCall().anyTimes(); 20 EasyMock.expect(reconciliation.getReconciliationEndTime()) 21 .andReturn(endTime); 22 EasyMock.expectLastCall().anyTimes(); 23 // TODO 2 24 reconciliation.setReconciliationStartTime( 25 sdf.parse(reconciliationStartTimeFormat.format(startTime))); 26 EasyMock.expectLastCall().anyTimes(); 27 reconciliation.setReconciliationEndTime( 28 sdf.parse(reconciliationEndTimeFormat.format(endTime))); 29 EasyMock.expectLastCall().anyTimes(); 30 reconciliation.setStatus((byte) 1); 31 EasyMock.replay(reconciliation); 32 QueryParameters queryParameters = new QueryParameters(); 33 queryParameters.setPage(1); 34 queryParameters.setRows(PAGESIZE); 35 ModelMap model = EasyMock.createMock(ModelMap.class); 36 // TODO 3 37 model.clear(); 38 39 EasyMock.expect(model.addAttribute("totalAmount", new Double(0))) 40 .andReturn(model); 41 EasyMock.expectLastCall().anyTimes(); 42 43 EasyMock.expect(model.addAttribute("total", new Integer(0))) 44 .andReturn(model); 45 EasyMock.expectLastCall().anyTimes(); 46 EasyMock.replay(model); 47 reconciliationController.getTotalAmount(reconciliation, queryParameters, 48 model); 49 } 50 /** 51 * 测试GetTotalAmount 52 * @throws ParseException 53 */ 54 @Test 55 public void testGetTotalAmount1() throws ParseException { 56 Reconciliation reconciliation = new Reconciliation(); 57 Date endTime = new Date(); 58 Date startTime = new Date(); 59 60 Calendar calendar = Calendar.getInstance(); 61 calendar.setTime(endTime); 62 calendar.add(Calendar.DATE, -1); 63 startTime = calendar.getTime(); 64 reconciliation.setReconciliationStartTime(startTime); 65 reconciliation.setReconciliationEndTime(endTime); 66 reconciliation.setStatus((byte) 1); 67 QueryParameters queryParameters = new QueryParameters(); 68 queryParameters.setPage(1); 69 queryParameters.setRows(PAGESIZE); 70 ModelMap model = new ModelMap(); 71 reconciliationController.getTotalAmount(reconciliation, queryParameters, 72 model); 73 }
被测单元:
/** * 运营审核--结算 */ @RequestMapping("/getTotalAmount") public void getTotalAmount(Reconciliation reconciliation, QueryParameters queryParameters, ModelMap model) { try { if (reconciliation.getReconciliationStartTime() == null) { logger.info("对账时没有选择对账开始时间!"); } else if (reconciliation.getReconciliationEndTime() == null) { logger.info("对账时没有选择对账截止时间!"); } else if (reconciliation.getReconciliationEndTime() .before(reconciliation.getReconciliationStartTime())) { logger.info("对账时,对账截止时间早于对账开始时间!"); } else { // 格式化日期时间 reconciliation.setReconciliationStartTime( sdf.parse(reconciliationStartTimeFormat.format( reconciliation.getReconciliationStartTime()))); reconciliation.setReconciliationEndTime( sdf.parse(reconciliationEndTimeFormat.format( reconciliation.getReconciliationEndTime()))); // reconciliations = // reconciliationManager.getReconciliation(reconciliationShopId, // reconciliationStartTime, reconciliationEndTime,status); } } catch (Exception e) { logger.error(e.getMessage()); } model.clear(); final Parameter[] parameters = ObjectToParam .getObjectInfo(reconciliation); double totalAmount = reconciliationManager .queryReconciliationTotalAmount(parameters); int total = reconciliationManager.queryReconciliationCount(parameters); model.put("totalAmount", totalAmount); model.put("total", total); }
上面的easymock的使用场景是在:知道参数的类型,但不知道参数的具体的值,但这种方式相对下面没有使用easymock的要麻烦的多,不占优势。
但是当被调用的方法没有编写完可以使用easymock赋一个固定的值,比如下面的代码:
1 /** 2 * easyMock测试更新 3 * 4 * @throws ParseException 5 */ 6 @Test 7 public void testuppdateReconciliation() throws ParseException { 8 IReconciliationManager reconciliationManager = EasyMock.createMock(IReconciliationManager.class); 9 Reconciliation reconciliation = new Reconciliation(); 10 String reconciliationId=""; 11 byte status = (byte)2; 12 ModelMap model = new ModelMap(); 13 EasyMock.expect(reconciliationManager.updateReconciliationStatus(reconciliation)).andReturn(false); 14 EasyMock.replay(reconciliationManager); 15 reconciliationController.getReconciliation(reconciliationId, status, model); 16 }
3、在写代码的时候遇到的问题
问题1:mock被多次调用需要使用EasyMock.expectLastCall().anyTimes(),否则有下列错误
java.lang.AssertionError:
Unexpected method call Reconciliation.getReconciliationEndTime():
Reconciliation.getReconciliationEndTime(): expected: 1, actual: 2
问题2:使用get填充之后,还需要使用mock填充set
java.lang.AssertionError: Unexpected method call Reconciliation.setReconciliationStartTime(Thu Sep 22 00:00:00 CST 2016): at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
问题3:map返回值多余一个
java.lang.IllegalStateException: missing behavior definition for the preceding method call: ModelMap.put("totalAmount", 0.0) Usage is: expect(a.foo()).andXXX()
相关讨论:
参考文档:http://outofmemory.cn/code-snippet/2370/java-danyuan-test-easyMock-usage-summary
http://www.educity.cn/se/619486.html