2013-03-12 63 views
3

我正在为JUnit4项目进行场景测试。JUnit4预期异常

在其中一个测试中,我需要检查预期的异常。使用JUnit4,我使用注释来完成此操作。

@Test(expected=...) 

现在的问题是,在抛出异常的测试代码的下面有我需要检查哪些没有得到excecuted其他一些注解。为例进行了说明:

@Test(expected=NullPointerException.class) 
    public void nullPointerTest() { 
     Object o = null; 
     o.toString(); 
     assertTrue(false); 
    } 

该测试通过,因为它得到的NullPointerException但有显然与asserTrue(假)断言错误,因此我希望它失败。

解决此问题的最佳方法是什么?对此的解决方案可能如下,但我不知道这是否是正确的方法。

@Test 
public void nullPointerTest2() { 
    boolean caught = false; 
    try{ 
     Object o = null; 
     o.toString(); 
    } 
    catch(NullPointerException e) 
    { 
     caught = true; 
    } 
    assertTrue(caught); 
    assertTrue(false); 
} 

第二个测试按预测失败。

+0

你为什么要做'assertTrue(false)'?或者这是否代表您的一些真实测试代码?这个“真实”的代码是否依赖于引发'NullPointerException'的代码? – rgettman 2013-03-12 00:19:59

+0

我不知道你为什么想要这样做。它闻起来糟糕的测试设计。每个测试只应该测试一件事情。 – Aurand 2013-03-12 00:22:43

+1

我建议你把它分成两个单独的测试。 – 2013-03-12 00:24:13

回答

3

JUnit4的行为如预期:抛出异常时,执行不会继续。所以NullPointerException被抛出,测试方法退出,JUnit4将其标记为传递,因为你期望有一个异常。空解除引用后的代码不存在。

如果你想要第二次测试的行为,那么你写的是一个很好的解决方案。但这是一件奇怪的事情要。在我看来,你正在混淆两个不同的测试。一个测试应该测试在特殊情况下抛出异常。第二个测试应该测试任何第二个断言检查。

+0

我不同意上面的例子是'怪异的'。考虑到在被测试类抛出异常的情况下,它可能还会在抛出异常之前执行其他可测试步骤(例如释放资源,记录错误,更新状态等) – 2013-03-12 11:08:24

+0

是的,如果它是*事先*处理异常,那么一切都会奏效。如果早期断言失败,测试将失败。如果后面的异常没有被抛出,那么测试将失败。有什么奇怪的是期待一个测试抛出一个异常,然后在*之后*做任何事情。抛出的异常是函数的结束(否则它不会被抛出,它会被捕获)。 – 2013-03-12 11:57:42

4

考虑:

@Test(expected=NullPointerException.class) 
public void nullPointerTest2() { 
    boolean caught = false; 
    try{ 
    Object o = null; 
    o.toString(); 
    } 
    catch(NullPointerException e) 
    { 
    // test other stuff here 
    throw e; 
    } 
} 

这允许额外的检查,同时还充分利用JUnit的内置的异常检查。

此外,我认为在许多情况下使用@Rule ExpectedException是更好的选择,即expected