自定义异常结合项目实战的测试

Posted 双子家的咸蛋蛋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义异常结合项目实战的测试相关的知识,希望对你有一定的参考价值。

 

-----------------------------引用部分-----------------------------------------------------

Java异常之自定义异常  转自https://www.cnblogs.com/AlanLee/p/6104492.html

Java 如何抛出异常、自定义异常  转自https://blog.csdn.net/qq_18505715/article/details/73196421

Java checked 异常 和 RuntimeException(运行时异常)  转自https://blog.csdn.net/qq_18505715/article/details/76696439

Java自定义异常,应该继承Exception还是Runtime Exception,为什么?转自https://www.zhihu.com/question/51970444?answer_deleted_redirect=true

 --------------------------------------引用部分-------------------------------------------------------

 

 

从逻辑的角度来看, checked 异常 和 RuntimeException 有着不同的使用目的,检查性异常 用来指示 一种调用方能够直接处理的异常情况(例如: 用户输入错误,程序可以直接捕获并处理,提示用户输入错误), 而RuntimeException 是用来指 调用方 本身无法 处理或回复 的程序错误(例如,你封装个库给别人用,当别人调用你库中某个方法是,需要传入某些参数,如果用户传入的参数不合法,你自己没办法处理,那么刺客你抛出的就应该是运行时异常)。

 

好吧,前面也看了不少相关的文章了,今天打算趁着周六有空,然后花点时间来实验一下.

 

在common_api工具类下新建自定义异常类继承运行时异常RuntimeException

public class InformationEmptyException extends RuntimeException {
    public InformationEmptyException(){
        super();
    }

    public InformationEmptyException(String message) {
        super(message);
    }
}

 

web下Controller测试test方法,页面传过来的参数policyno 为一长串数字

@RestController
@RequestMapping("/edor/common")
public class EdorCommonController extends BaseController {

    @Autowired
    private IEdorCommonController iEdorCommonController;

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ModelAndView test(){
        HttpServletRequest request = this.getRequest();
        String policyno = request.getParameter("policyno");
        if ("1".equals(policyno)) {
            request.setAttribute("mess", "policyno不能为1");
            return go("/edor/survivalgoldreceive/sgerrormessage");
        }else {
            try{
                iEdorCommonController.test(ver,policyno);
                return go("/edor/survivalgoldreceive/sgerrormessage");
            }catch (Exception e) {
                e.printStackTrace();
                logger.error("EdorCommonServiceImpl报出异常 : " + e.getMessage());
                request.setAttribute("mess", "出现系统级别的错误!");
                return go("/edor/survivalgoldreceive/sgerrormessage");
            }
        }

    }

 

Spring Cloud 分发组件Feign接口, 只测试test方法, 这里经过测试抛出自定义异常还是Exception都是一样

@FeignClient(name = "service-edor")
public interface IEdorCommonController {

    /**根据客户号查询GeCustomerProperty*/
    @RequestMapping(value="/service-edor/common/{version}/getGeCustomerPropertyByCustomerNo", method = RequestMethod.GET)
    ReturnInfoVo<Object> getGeCustomerPropertyByCustomerNo(@PathVariable("version") String version,
                                                           @RequestParam("customerNo") String customerNo);

    @RequestMapping(value="/service-edor/common/{version}/test", method = RequestMethod.GET)
    void test(@PathVariable("version") String version,@RequestParam("policyno") String policyno) throws InformationEmptyException;

}

 

微服务edor的Controller,只测试test方法

@RestController
@RequestMapping(value = "/service-edor/common/{version}")
public class EdorCommonContrller extends BaseController {
    @Resource
    private EdorCommonServiceImpl edorCommonServiceImpl;
    /**根据客户号查询GeCustomerProperty*/
    @RequestMapping(value="/getGeCustomerPropertyByCustomerNo", method = RequestMethod.GET)
    public ReturnInfoVo<Object> getGeCustomerPropertyByCustomerNo(@PathVariable("version") String version,
                                                                  @RequestParam("customerNo") String customerNo){
        return edorCommonServiceImpl.getGeCustomerPropertyByCustomerNo(customerNo);
    }

    @RequestMapping(value="/test", method = RequestMethod.GET)
    public void test(@PathVariable("version") String version,@RequestParam("policyno") String policyno) throws InformationEmptyException {
        edorCommonServiceImpl.test(policyno);
    }
}

 

微服务edor的Service层EdorCommonServiceImpl ,只测试test方法

@Service("edorCommonServiceImpl")
public class EdorCommonServiceImpl extends BaseService implements IEdorCommonService {
    @Resource
    private GeCustomerPropertyMapper geCustomerPropertyMapper;
    /**
     * 根据客户号查询GeCustomerProperty
     * @param customerNo
     * @return
     */
    @Override
    @Transactional(propagation=Propagation.SUPPORTS)
    public ReturnInfoVo<Object> getGeCustomerPropertyByCustomerNo(String customerNo) {
        ReturnInfoVo<Object> infoVo = new ReturnInfoVo<>();
        GeCustomerProperty geCustomerProperty = geCustomerPropertyMapper.selectByPrimaryKey(customerNo);
        if (geCustomerProperty != null) {
            String geCustomerPropertyStr = JsonUtils.toJson(geCustomerProperty);
            infoVo.setResult(geCustomerPropertyStr);
        }
        return infoVo;
    }

    public void test(String policyno) throws InformationEmptyException{
        if (!"2".equals(policyno)) {
            throw new InformationEmptyException("参数不等于2");
        }
    }
}

 

测试结果 : 

微服务edor下的Service层EdorCommonServiceImpl弹出异常

 

web下Controller弹出异常:

 

清空控制台后,只看logger.error日志输出的信息

结果是异常的详细信息上半部分是分发组件Feign接口报的异常,content里面的exception才是我们自定义的异常. 

 

 

现在把web下Controller中try catch到的异常改为InfomationEmptyException再试

 

 

 

web下Controller这次的结果没并有停留在断点处,而直接结束了,报出的异常如下

 

 说明在web下Controller这里用InfomationEmptyException作为接收的异常不可取,再试试用FeignException

 

 这次接收到了,跳到了断点处

看控制台报出的异常,基本和用Exception作为接收异常的结果一样.

 

测试结论 : 如果在微服务中使用了自定义异常,那么在web下的Controller只要是通过调用了Feign接口,那么只能用FeignExcepion或者Exception进行接收,而且自定义异样报出的异常信息在content里面

 

 

 

 

 

 

 

 

现在测试不走Feign接口,直接用WEB下的另一个类来抛异常,然后Controller来接收

同级目录下新建类

public class Test {
    
    public void test(String policyno) throws InformationEmptyException {
        if (!"2".equals(policyno)) {
            throw new InformationEmptyException("参数不等于2");
        }
    }

}

Web下Controller进行调用,用InfomationEmptyException进行接收

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ModelAndView test(){
        HttpServletRequest request = this.getRequest();
        String policyno = request.getParameter("policyno");
        if ("1".equals(policyno)) {
            request.setAttribute("mess", "policyno只能为1");
            return go("/edor/survivalgoldreceive/sgerrormessage");
        }else {
            try{
                new Test().test(policyno);
                return go("/edor/survivalgoldreceive/sgerrormessage");
            }catch (InformationEmptyException e) {
                e.printStackTrace();
                logger.error("EdorCommonServiceImpl报出异常 : " + e.getMessage());
                request.setAttribute("mess", "出现系统级别的错误 !");
                return go("/edor/survivalgoldreceive/sgerrormessage");
            }
        }

    }

 

测试结果:

符合预期,直接报出了两个异常的来源,而且异常信息也没有被包裹着

 

清空控制台,查看logger.error的日志信息 

 

 

 

 现在再把Web下的Controller改为Exception接收异常

 

 

测试结果:

结果还是一样,说明在最外层用Exception接收是没毛病的

再清空控制台看logger日志

 

 

 

 

最后总结,自定义异常确实是挺好分辨,也能够直接定位,但前提是不通过Feign接口走微服务.如果通过了Feign接口,那么最外层只能以FeignException或者Exception进行接收.因为不管你在Feign接口那写的抛出什么异样,它最终都会抛出FeignException.

但是自定义异样的信息可以在content里面进行查看

 

 

以上是关于自定义异常结合项目实战的测试的主要内容,如果未能解决你的问题,请参考以下文章

springBoot 自定义注解 + 自定义异常捕获实战

片段中的自定义列表适配器

微服务架构整理-(九SpringCloud实战之Hystrix [2])

微服务架构整理-(九SpringCloud实战之Hystrix [2])

自定义封装Exception异常抛出

单元测试 NPE,当我添加片段自定义转换时