在JUnit测试中捕获AssertionError是个好主意吗?

时间:2013-08-14 01:14:55

标签: java junit4

我有一个对象作为API调用的结果,我想断言成员变量的值。

此值可以是两个预期值中的一个,具体取决于API调用首先“看到”并首先设置。因此,如果对一个值的断言失败,我想在将测试声明为失败之前声明另一个值。

这样做的最佳方式是什么?我现在拥有的是:

try {
    assertEquals("message", someObject.getValue1(), expectedValue1); 
} catch(AssertionError ae) {
    assertEquals("message", someObject.getValue1(), expectedValue2); 
}

我不确定这是否是可接受的做法。请评论。

3 个答案:

答案 0 :(得分:7)

使用异常作为一种美化的goto语句通常不是一个好习惯。或者至少你会遇到职业生涯中那些对程序流程控制使用异常采取模糊观点的人。

怎么样:

Assert.assertTrue((someObject.getValue1().equals(expectedValue1) || (someObject.getValue2().equals(expectedValue2));

答案 1 :(得分:6)

取决于目的,自动功能测试或单元测试。我有时会为前者做这件事:

try {
    assertTrue(boolean condition from earlier in test method to check);
}
catch(AssertionError uhOh) {
     Logger.err("condition X failed: detailed info msg"); // broken item #1

}

try {
    assertTrue(another condition in same method to check);
}
catch(AssertionError yuck) {
     Logger.err("condition X failed: detailed info msg"); // another broken item
     fail(); // now blow up as we've checked everything
}

当然,使用logback Logger和JUnit的Assert.fail()会导致测试方法失败。这样我知道这种方法的所有失败,而不是在第一次失败之后爆炸。就我而言,我正在测试一个内容丰富的Web应用程序(需要大量用户输入的对话框和页面)。

"'快速失败'" (没有捕获)发现一个问题,修复它,再次运行并找到一个新问题("冲洗和重复"),但如果用于单元测试,由于测试的模块化,这是一项资产(理想情况下,每个测试只测试一个项目的一个方面)。

答案 2 :(得分:1)

我同意Aquilon关于这不是好的做法。

但是,您是否可以使用模拟或其他机制来“强制”API“看到”一个项目先于另一个项目?这样,您的测试可以反映导致一个断言在一个测试中为真的条件,而另一个断言在另一个测试中为真。