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

当我偶然发现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
interface ThrowableRunnable {
    void run() throws Throwable;
}

// Assert a Throwable type
static void assertThrows(
    Class<? extends Throwable> throwable,
    ThrowableRunnable runnable
) {
    assertThrows(throwable, runnable, t -> {});
}

// Assert a Throwable type and implement more
// assertions in a consumer
static void assertThrows(
    Class<? extends Throwable> throwable,
    ThrowableRunnable runnable,
    Consumer<Throwable> exceptionConsumer
) {
    boolean fail = 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, () -> { throw new Exception(); });
assertThrows(Exception.class, 
    () -> { throw new Exception("Message"); },
    e  -> assertEquals("Message", e.getMessage()));

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

// This essentially swallows exceptions
static void withExceptions(
    ThrowableRunnable runnable
) {
    withExceptions(runnable, t -> {});
}

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

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

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

withExceptions(
    // This will fail
    () -> assertThrows(SQLException.class, () -> { throw new Exception();}),
    t -> t.printStackTrace()

);

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

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

原文链接: dzone 翻译: ImportNew.com - xbing
译文链接: http://www.importnew.com/12581.html
[ 转载请保留原文出处、译者和译文链接。]

关于作者: xbing

(新浪微博:@蓝心MO

查看xbing的更多文章 >>



相关文章

发表评论

Comment form

(*) 表示必填项

还没有评论。

跳到底部
返回顶部