在大多数JUnittesting中抛出Exception是否违背最佳实践?

几乎所有的JUnittesting都是用以下签名书写的:

public void testSomething() throws Exception 

我的推理是我可以专注于我正在testing的内容,而不是JUnit似乎给我免费的exception处理。 但是我这样做是否错过了什么? 这是否违背最佳做法? 我会通过在testing中明确捕获特定的exception,然后失败()来获得任何东西吗?

一般来说,如果你正在testing的情况下,你不希望发生一个exception,那么我只是让testing方法抛出exception,因为它将很好地区分失败的testing用例(他们不通过你的断言)和错误testing用例(它们导致意外的exception)。 JUnit TestRunners将捕获抛出的exception,无论如何,如果引发exception,您不必担心整个testing套件都会陷入困境。

另一方面,如果您正在编写一个应该触发exception的testing,那么您要么使用JUnit 4注释的@Test(expected=IllegalArgumentException.class)变体,要么使用更常见的JUnit 3成语:

 try { target.someMethodToTest(); fail("Should have gotten an exception"); } catch (IllegalStateException ise) { //expected, it's all good } 

不要抓住和失败 – 你将失去宝贵的信息。 让所有的例外都飞出去。 这意味着你需要添加每个检查的exception你可以抛出的签名。 不过,我build议你不要懒惰的方式,盲目地使用throws Exception作为一个习惯的问题。 这使你甚至不必考虑你的API在exception方面的performance。

主要的好处涉及到当你testing一些需要抛出Exception的场景时(比如err-r处理)

你可以在JUnit4中使用类似于@Test(expected = ArithmeticException.class)的东西,但是有些人发现比显式的try {catch(Exception e)块更难读/更less的意图显示,如果你想检查状态(例如某个模拟对象,或者查看exception是在正确的地方,还是logging等等)

如果抛出一个exception,而你并不期待,那么testing就会失败。

如果这是一个未经检查的exception,我允许抛出exception,让JUnit不能通过testing。

如果是检查exception,则可以select:将exception添加到方法签名的throws子句中,或者将其捕获到方法中。 编译器会强制你select,因为如果没有这些select,你将无法运行代码。

最近我倾向于不在我的testing中捕捉exception。 如果它应该抛出一个exception,我用标注标记它。 如果它抛出一个未经检查的exception,我离开了JUnit的testing失败了。 如果它是一个检查exception,我将throws子句添加到方法签名中,并让JUnit使我的testing失败。