在大多数JUnit测试中抛出异常是否违反最佳做法?

Chr*_*ght 44 java junit unit-testing

几乎所有的JUnit测试都使用以下签名编写:

public void testSomething() throws Exception
Run Code Online (Sandbox Code Playgroud)

我的理由是我可以专注于我正在测试的内容,而不是JUnit似乎免费提供给我的异常处理.但这样做我错过了什么吗?这是违反最佳做法的吗?我可以通过在测试中明确捕获特定异常然后失败()来获取任何东西吗?

Oph*_*ian 55

一般情况下,如果您正在测试一个您不希望发生异常的情况,那么我只是让测试方法抛出异常,因为它可以很好地区分失败的测试用例(它们没有通过你的一个)断言)和错误测试用例(它们会导致意外的异常).JUnit TestRunners将捕获抛出的异常,因为如果抛出异常,您不必担心整个测试套件的失败.

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

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

  • 这是最好的答案.我要补充一点,我认为这里的问题是风格:捕捉失败,还是抛出?通常,最佳做法是避免"抛出异常".原因是它使API用户的异常处理毫无意义.但这里没有这样的用户.所以"抛出异常"是正确的做法. (4认同)

Kev*_*ion 11

不要抓住和失败 - 你将丢失有价值的信息.让所有例外都飞出来.这意味着您需要为每个已检查的异常添加可以抛出的签名.但是,我建议你不要采取懒惰的方式,盲目地使用throws Exception习惯.这使您甚至不必考虑 API在异常方面的真实行为.

  • 恕我直言,在测试方法中添加已检查异常的完整列表并没有带来太多好处,实际上妨碍了测试签名的可读性(特别是如果SUT可以抛出很多例外). (5认同)