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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18221712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:26:23  来源:igfitidea点击:

Is it a good idea to catch AssertionError in JUnit tests?

javajunit4

提问by Shine

I have an object as the result of an API call and I want to assert the values of a member variable.

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

This value can be one of the two expected values depending on what the API call "sees" first and sets first. So if the assertion on one value fails, I want to assert for another value before declaring the test as a failure.

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

What is the best way of doing this? What I have right now is:

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

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

I am just not sure if this is an acceptable practice. Please comment.

我只是不确定这是否是可以接受的做法。请给出意见。

采纳答案by Dominic Tracey

Using exceptions as a sort of glorified goto statement is generally not a good practice. Or at least you will run into people in your career who take a dim view of using exceptions for program flow control.

使用异常作为一种美化的 goto 语句通常不是一个好习惯。或者至少你会遇到在你的职业生涯中对使用异常进行程序流控制持悲观态度的人。

How about:

怎么样:

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

回答by Steven M. Wurster

I'll agree with Aquilon regarding this not being good practice.

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

However, can you use mocking or some other mechanism to "force" the API "see" one item before the other? That way your tests can reflect the conditions that lead to one assertion being true in one test, and the other assertion being true in another test.

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

回答by DYezek

Depends on the purpose, automated functional testing or unit testing. I sometimes do this for the former:

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

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
}

Of course that's using logback Logger and JUnit's Assert.fail() which fails the test method. This way I know of all failures for this method rather than blowing up after the first. In my case, I'm testing a rich-content web app (dialogs and pages that take a lot of user input).

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

Downside of "fail-fast" (using no catches) is finding one problem, fixing it, running again and finding a new one ("rinse and repeat"), but if used for unit testing this is an asset due to the modularity of the tests (ideally you are only testing one aspect of an item per test).

“快速失败”(不使用捕获)的缺点是发现一个问题,修复它,再次运行并找到一个新的(“冲洗并重复”),但如果用于单元测试,这是一种资产,因为它的模块化测试(理想情况下,您每次测试只测试项目的一个方面)。