首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

jmockit-mock

2012-12-15 
jmockit------mock刚进公司,写两个星期的单元测试。公司主要用Jmockit ,感觉用起来还不错,于是乎,把一些写

jmockit------mock

刚进公司,写两个星期的单元测试。公司主要用Jmockit ,感觉用起来还不错,于是乎,把一些写单测的时候,常遇到的写法写了下来。

?

凡是单元测试,都需要做以下几件事情

1, 明确要测试的类,和方法

2, 明确测试的实现,需要哪些依赖

3, 针对这些外部依赖 进行 mock

4, 验证是否根据自己的输入取得自己的输出

?

那么在JMOCKIT中。

做到1 这点,使用@Tested这个 注解

做到2这点,使用@injected 这个注解

做到3这点,可以使用?Expectations 和?NonStrictExpectations

做到4这点,则可以使用junit 的Assert 或者?Verifications

?

那么常见的写法就贴个出来:

?

?

?

@Tested@Mocked(methods = "updateEditNum")private CustomerServiceImplcustomerServiceImpl;@Injectableprivate CustomerDaocustomerDao;@Injectableprivate CustOptionalDaocustOptionalDao;@Injectableprivate CustAccountInfoDaocustAccountInfoDao;@Injectableprivate CustContactPhoneDaocustContactPhoneDao;@Injectableprivate CustContactDaocustContactDao;@Injectableprivate CustRecipDaocustRecipDao;@Injectableprivate CustAutoAuditInfoDaocustAutoAuditInfoDao; // 需要修改monogo数据@Testpublic void testUpdateCustomer_need_update_monogo() {CustomerVO customerVO = buildCustomer();nonstrictExpectations();customerServiceImpl.updateCustomer(customerVO);new Verifications() {{mongoUpdateService.modSaleData(anyLong, anyString);times = 1;mongoCoreWordFacade.modCoreWordData(anyLong, anyString, anyLong);times = 1;}};}private void nonstrictExpectations() {new NonStrictExpectations() {{customerServiceImpl.updateEditNum((CustomerVO) any, (Map<String, Short>) any);result = null;customerDao.findById(anyLong);Customer customer = new Customer();customer.setFullName("unit test fullname change");customer.setStat1(StatMachineService.STAT1_IN_FOLLOWING_04);result = customer;custContactDao.saveOrUpdate((CustContact) any);CustContact c = new CustContact();c.setContactId(11l);result = c;custContactPhoneDao.saveOrUpdate((CustContactPhone) any);CustContactPhone p = new CustContactPhone();p.setPhoneId(22l);result = p;}};}

?

最常用的有了,但单元测试可不是那么简单。我这边碰到第一个情景是,测试一个service.doXXX() 。

但这个 doXXX()其实里面就调用了2个private方法,那么其实问题就转变成分别测试这两个private 方法:

?

主要使用的是:Deencapsulation

?

// 测试私有方法获取该类型的para数据字典 (不传 单位岗位ID)@Testpublic void testFindByTypeAndPosIdWithCache_NO_POS() {new NonStrictExpectations() {{paraDao.findByTypeAndPosid(ParaTypeEnum.auditAbandReason);List<Para> pararet = new ArrayList<Para>();Para p = new Para();p.setDelFlag((short) 0);p.setShare((short) 0);p.setName("这个客户不是火星来的么,所以不能审核通过的!");pararet.add(p);returns(pararet);}};List<Para> rets = Deencapsulation.invoke(paramServiceImpl, "findByTypeAndPosIdWithCache",ParaTypeEnum.auditAbandReason, new Long[] {});Assert.assertTrue(rets.get(0).getName().equals("这个客户不是火星来的么,所以不能审核通过的!"));new Verifications() {{calloutMemcachedClient.get(anyString);times = 1;calloutMemcachedClient.set(anyString, anyInt, anyString);times = 1;}};}
?

但是查看源码 发现 继承于?Invocations的?Expectations 和?Verifications 也都是有invoke 的反射方法已经提供好了。

?

?

第二种情况来了,我要测试的@Tested 类,里面本身也有需要mock 的方法,但只 mock 其中一个方法就够了

?

?

        @Tested@Mocked(methods = "updateEditNum")private CustomerServiceImplcustomerServiceImpl;
?

第三种情况来了,有个实现的地方需要mock ,但这个实现是这样的 A.doAA().doBB().doCC()

?

?

难道要先mock A.doAA(),然后在mock这个返回值的doBB() 。。。。 太麻烦了

?

来看下:

// 测试用户信息比较全,并且需要优先审核,会更新优先统计数@Testpublic void testAddCustomer(@Cascading final ServiceLocator ServiceLocator) {long custId = 38888888l;CustomerVO vo = new CustomerVO();vo.setFullName("单元测试用户");vo.setCustId(custId);。。。。。new NonStrictExpectations() {{ServiceLocator.getInstance().getBean("saleSetFacade");saleSetFacade = new SaleSetFacade() {public SaleSet findSaleSetById(Long id) {return null;}。。。。。。};result = saleSetFacade;}};
?

?

?

?

?

?

?

?

热点排行