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

时间:2016-12-12 14:14:23

标签: java unit-testing junit junit4

我没有在JUnit测试中进行异常处理,而是使用... throws Exception声明我的测试方法?

我开始这样做,我没有理由为什么我应该更具体。

2 个答案:

答案 0 :(得分:12)

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

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

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

因此:有捕获块;而且在99.999%的情况下,将测试方法签名的潜在投掷原因添加为正确的答案。或者100%;因为我找不到一个好的反例。

但是我会谨慎地使用throws Exception快速。您仍然希望您的代码尽可能“具体”;最好去throws ThatExceptionThatCanReallyBeThrown。当这个列表过于频繁地变得太长时......那么你最好跟进那一侧并检查你的生产代码中的抛出列表是否应该以某种方式“削减”。

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

  1. 不抛出异常
  2. 抛出一个特定的例外(然后你会做@Test(expected=...)
  3. 抛出一个特定的异常...您的测试需要捕获以进一步检查
  4. 抛出一个异常......这将表明一个真正的“错误”状态(因为你没想到它会发生);在这种情况下,JUnit将捕获异常并将其作为失败的测试用例报告给您。 (但是,当然,请记住,JUnit中的测试用例错误和测试失败存在细微差别。)
  5. throws X, Y放在测试方法签名上是解决项目符号2和4的直接方法。

答案 1 :(得分: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")
  }
}