当前访客身份:游客 [ 登录  | 注册加入尚学堂]
启用新域名sxt.cn
新闻资讯

更好的异常处理:实现JUnit API

helloworld 发表于 2年前  | 评论(0 )| 阅读次数(538 )|   0 人收藏此文章,   我要收藏

当我偶然发现JUnit的GitHub上issue编号#706问题(译注:为JUnit增加一个新API),想到了一个新的处理方法:

ExpectedException#expect(Throwable, Callable)




一方面,建议可以像这样创建一个拦截器。

 
	
assertEquals(Exception.class, thrown(() -> foo()).getClass());
assertEquals("yikes!", thrown(() -> foo()).getMessage());




另一方面,为什么不像下面这样这样重新?

// This is needed to allow for throwing Throwables
// from lambda expressions
@FunctionalInterface
interfaceThrowableRunnable {
    voidrun()throwsThrowable;
}
 
// Assert a Throwable type
staticvoidassertThrows(
    Class<?extendsThrowable> throwable,
    ThrowableRunnable runnable
) {
    assertThrows(throwable, runnable, t -> {});
}
 
// Assert a Throwable type and implement more
// assertions in a consumer
staticvoidassertThrows(
    Class<?extendsThrowable> throwable,
    ThrowableRunnable runnable,
    Consumer<Throwable> exceptionConsumer
) {
    booleanfail =false;
    try{
        runnable.run();
        fail =true;
    }
    catch(Throwable t) {
        if(!throwable.isInstance(t))
            Assert.fail("Bad exception type");
        exceptionConsumer.accept(t);
    }




 	
    if(fail)
        Assert.fail("No exception was thrown");
}




因为大部分功能接口不能抛出Checked异常,所以上面的方法断言:从具体的Runnable-ThrowableRunnable抛出的相应Throwable。

现在我们按照上面想象的JUnit API进行:

assertThrows(Exception.class, () -> {thrownewException(); });
assertThrows(Exception.class,
    () -> {thrownewException("Message"); },
    e  -> assertEquals("Message", e.getMessage()));




事实上,甚至我们可以更进一步写出类似下面的帮助方法:

// This essentially swallows exceptions
staticvoidwithExceptions(
    ThrowableRunnable runnable
) {
    withExceptions(runnable, t -> {});
}
 
// This delegates exception handling to a consumer
staticvoidwithExceptions(
    ThrowableRunnable runnable,
    Consumer<Throwable> exceptionConsumer
) {
    try{
        runnable.run();
    }
    catch(Throwable t) {
        exceptionConsumer.accept(t);
    }
}




这样处理各种异常非常有用。下面是两种常用方法:

try{
    // This will fail
    assertThrows(SQLException.class, () -> {thrownewException(); });
}
catch(Throwable t) {
    t.printStackTrace();
}
 
withExceptions(
    // This will fail
    () -> assertThrows(SQLException.class, () -> {thrownewException();}),
    t -> t.printStackTrace()
 
);




由于这些方法对很多异常类型和try-with-resources支持不够好,不见得比常用的try..catch..finally语句块有用。

但是这样的方法以后会在日常中用到。

分享到:0
关注微信,跟着我们扩展技术视野。每天推送IT新技术文章,每周聚焦一门新技术。微信二维码如下:
微信公众账号:尚学堂(微信号:bjsxt-java)
声明:博客文章版权属于原创作者,受法律保护。如果侵犯了您的权利,请联系管理员,我们将及时删除!
(邮箱:webmaster#sxt.cn(#换为@))
北京总部地址:北京市海淀区西三旗桥东建材城西路85号神州科技园B座三层尚学堂 咨询电话:400-009-1906 010-56233821
Copyright 2007-2015 北京尚学堂科技有限公司 京ICP备13018289号-1 京公网安备11010802015183