你有木有遇到过这种情况,在为一个复杂业务方法写单个单元测试时,你需要做一大堆初始化工作,主要是各种service,你也可以直接把总个容器初始化(如果你使用spring等容器的话),如果项目比较大,运行单个测试,得等上几十秒,你hold住吗,可以参照我的方法进行加速(http://mingliang-luo.iteye.com/blog/1258830);
现在就复杂业务方法写单元测试给出一个解决方案:我采用的是【 继承 + easyMock 】,也可以使用【easyMock class + easyMock】;
一个复杂业务方法内,会调用此类中很多的方法,而你的测试又与之无关,这时,你可以使用继承,直接重写那个方法,那么,这个方法内的初始化工作就不需要做了,当然,你也可以使用【easyMock class】重写;
但如果不是调用此类的方法,而是调用其它service中的方法,那你可以直接使用easyMock代替真实的service;
采用这种方式后,你就可以快速编写这种复杂业务逻辑的测试了,并且它可以运行得很快。
下面是我的一个测试,仅供参考:
static MemberService memberService; //需要测试的方法 static SqlSession sqlSession; @BeforeClass public static void beforeClass() throws Exception{ sqlSession = SessionFactory.getSqlSession(); MemberServiceImpl memberServiceImpl = new MemberServiceImpl(); MemberDao memberDao = new MemberDao(); memberDao.setMemberMapper((MemberMapper)SessionFactory.getMapper(MemberMapper.class, sqlSession)); memberServiceImpl.setMemberDao(memberDao); memberService = memberServiceImpl; ReturnFreeToCustomerByFirstRefundOrChangeTest re = new ReturnFreeToCustomerByFirstRefundOrChangeTest(); re.setMemberService(memberServiceImpl); changOrRefundService = re; } //第一次退换货,返运费,15元 @Test public void testReturnFreeToCustomer1th() throws Exception{ ChangOrRefundAssistant cra = new ChangOrRefundAssistant(); cra.setOrderCd("110927001086NT"); cra.setRefundType(NoneyReturnedConstants.REFUNDTYPE_TH); Order order = new Order(); order.setOrderCd(cra.getOrderCd()); order.setMemberId(239l); Float account = memberService.queryAccountBalanceByMemberId(order.getMemberId()); //无关的service OrderCCService orderCCService = createMock(OrderCCService.class); orderCCService.returnedInventory(EasyMock.anyObject(), EasyMock. >anyObject()); expect(orderCCService.genOrderLog(EasyMock.
anyObject())).andReturn(1); expect(orderCCService.loadOrdertByCd(EasyMock. anyObject())).andReturn(order); replay(orderCCService); changOrRefundService.setOrderCCService(orderCCService); //退货 changOrRefundService.refundByWarehouseRMI(cra); sqlSession.clearCache(); Float accountAfter = memberService.queryAccountBalanceByMemberId(order.getMemberId()); //[帐户增加15元] assertEquals(15, accountAfter - account, 0.001); List logs = memberService.queryAccountLogs(order.getMemberId()); AccountLog lastLog = logs.get(0); //[存入] [15元] [退换货返运费,订单为xxxxxx] assertEquals(Constants.MBS_ACCOUNT_TRADE_TYPE_1, lastLog.getTradeType()); assertEquals(15, lastLog.getAmount(), 0.001); assertTrue(lastLog.getNote().startsWith("退换货返运费")); assertTrue(lastLog.getNote().contains(order.getOrderCd())); }//下面的全是refundByWarehouseRM会调用的方法,不关心,直接pass public ChangOrRefund queryChgOrRefdByOrderId(Long orderId) throws Exception{ return new ChangOrRefund(); } public List loadChangOrRefundDetailByChgId(Long id)throws Exception { return new ArrayList (); } public List genOrderItemByRefund(List lstDetails,Long orderId)throws Exception{ return null; } public void updateOrderItemByWhouse(Long orderItemID,String refundType) throws Exception{ } public void deductInventoryByChange(String channelCode,List lstChgItem) throws Exception{ } public void updateOrderByWH(ChangOrRefundAssistant changOrRefundAssistant,Order order) throws Exception{ }