在 JUnit 测试中抛出所有异常是不好的做法吗?

Is it bad practice to just throw all Exceptions in a JUnit test?

我没有在我的 JUnit 测试中进行异常处理,我只是用 ... throws Exception?

声明我的测试方法

我开始这样做了,但我看不出我应该更具体的原因。

单元测试的核心方面是帮助您尽快隔离/解决生产代码中的错误。

从这个意义上讲:您编写@Test 方法不是为了被其他方法调用。您编写它们以便 JUnit 框架运行它们。

通常,当该测试抛出异常时;捕捉它是没有意义的(除非它是预期的;并且您想进一步检查该异常)。

因此:没有有catch块;在 99.999% 的情况下,将潜在的抛出原因添加到您的测试方法签名中是正确的答案。或者可能是 100%;因为我找不到好的反例。

但我会小心使用 throws Exception 来快速。您仍然希望您的代码尽可能 "specific";所以最好选择 throws ThatExceptionThatCanReallyBeThrown。当该列表经常变得太长时......那么你最好在那边跟进并检查你的生产代码中的抛出列表是否应该 "trimmed" 以某种方式下降。

编辑:可能要理解的核心内容是:对于您的每一个测试,您对将要发生的事情都有一个确切的期望。该方法应该:

  1. 不抛出异常
  2. 抛出一个特定的异常(然后你会做 @Test(expected=...) 事情
  3. 抛出特定异常...您的测试需要捕获该异常以进行进一步检查
  4. 抛出一个异常...这将指示一个真正的 "error" 条件(因为您没有预料到它会发生);在这种情况下,JUnit 将捕获异常并将其作为失败的测试用例报告给您。 (当然,请记住,JUnit 中的测试用例错误和测试失败存在细微差别)。

throws X, Y 放在您的测试方法签名上是解决项目符号 2 和 4 的直接方法。

除了@GhostCat回答还想说—— JUnit 有一个很好的功能,名为 Rules。它非常适合测试异常,可能比 @Test(expected=Whatever.class).

更好

用法示例:

public class Test {
  @Rule
  public final ExpectedException thrown = ExpectedException.none();

  private MyService myService;

  @Before
  public void setUp() {
    myService = new MyService ();
  }
  @Test
  public void exceptionTest() throws MyException {
    thrown.expect(MyException.class);
    thrown.expectMessage("my description");
    myService.create("bad argument"); //throws MyException("my description")
  }
}