java 在大多数 JUnit 测试中抛出异常是否违反最佳实践?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2496525/
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-10-29 21:29:20  来源:igfitidea点击:

Is it against best practice to throw Exception on most JUnit tests?

javaunit-testingjunit

提问by Chris Knight

Almost all of my JUnit tests are written with the following signature:

我几乎所有的 JUnit 测试都是用以下签名编写的:

public void testSomething() throws Exception

My reasoning is that I can focus on what I'm testing rather than exception handling which JUnit appears to give me for free. But am I missing anything by doing this? Is it against best practice? Would I gain anything by explicitly catching specific exceptions in my test and then fail()'ing on them?

我的理由是,我可以专注于我正在测试的内容,而不是 JUnit 似乎免费提供给我的异常处理。但是这样做我错过了什么吗?是否违反最佳实践?通过在我的测试中明确捕获特定异常然后对它们进行失败(),我会得到什么吗?

回答by Ophidian

In general, if you are testing a case where you do not expect an Exception to occur, then I would just let the test method throw Exception as you have illustrated since it will nicely differentiate between Failingtest cases (they do not pass one of your assertions) and Errortest cases (they cause an unexpected Exception). The JUnit TestRunners will catch the thrown Exception regardless so you don't have to worry about your entire test suite bailing out if an Exception is thrown.

一般来说,如果您正在测试一个您不希望发生异常的情况,那么我只会让测试方法抛出异常,正如您所说明的那样,因为它可以很好地区分失败的测试用例(它们不会通过您的一个断言)和错误测试用例(它们会导致意外异常)。无论如何,JUnit TestRunners 都会捕获抛出的异常,因此您不必担心如果抛出异常,您的整个测试套件就会退出。

On the other hand, if you are writing a test that is supposed to trigger an exception, then you either want to use the @Test(expected=IllegalArgumentException.class)variant of the JUnit 4 annotation, or the more common JUnit 3 idiom of:

另一方面,如果您正在编写一个应该触发异常的测试,那么您要么想使用@Test(expected=IllegalArgumentException.class)JUnit 4 注释的变体,要么使用更常见的 JUnit 3 惯用语:

try {
  target.someMethodToTest();
  fail("Should have gotten an exception");
} catch (IllegalStateException ise) {
  //expected, it's all good
}

回答by Kevin Bourrillion

Do NOT catch and fail -- you will lose valuable information. Let all exceptions fly right on out. This means you need to add each checked exception your signature that can be thrown. However, I'd advise you not to take the lazy way out and blindly use throws Exceptionas a matter of habit. This excuses you from ever even having to thinkabout how your API really behaves with respect to exceptions.

不要抓住并失败——你会丢失有价值的信息。让所有的例外都飞出去。这意味着您需要添加每个可以抛出的签名的已检查异常。不过,我劝你不要偷懒throws Exception,习惯性地盲目使用。这使您无需考虑您的 API 在异常方面的实际行为。

回答by jayshao

The main benefit involves when you are testing some scenario that requires an Exception to be thrown (e.g. err-r handling)

主要好处涉及当您测试某些需要抛出异常的场景时(例如 err-r 处理)

You can in JUnit4 use something like: @Test(expected=ArithmeticException.class) but some people find that to be harder to read/less intention revealing than an explicit try{} catch (Exception e) block, and if you wanted to check state (say of some mock object, or to see if the exception was thrown in the right place, or logged, or the like)

你可以在 JUnit4 中使用类似的东西:@Test(expected=ArithmeticException.class) 但有些人发现它比显式的 try{} catch (Exception e) 块更难阅读/更少的意图揭示,如果你想检查状态(比如一些模拟对象,或者查看异常是否被抛出到正确的位置,或者被记录,等等)

回答by duffymo

If an exception is thrown, and you're not expecting it, the test should fail.

如果抛出异常,并且您没有预料到它,则测试应该失败。

If it's an unchecked exception I allow the exception to be thrown and have JUnit fail the test.

如果它是未经检查的异常,我允许抛出异常并使 JUnit 测试失败。

If it's a checked exception, you have a choice: either add the exception to the throws clause of the method signature or catch it inside the method. The compiler will force a choice on you, because you can't run the code without either of these choices.

如果它是一个已检查的异常,您有一个选择:要么将异常添加到方法签名的 throws 子句中,要么在方法内部捕获它。编译器将强制您做出选择,因为没有这些选择中的任何一个,您都无法运行代码。

Lately I've tended to not catch exceptions inside my tests. If it's supposed to throw an exception, I mark it as such with the annotation. If it throws an unchecked exception, I left JUnit fail the test for me. If it's a checked exception, I add the throws clause to the method signature and left JUnit fail the test for me.

最近我倾向于在我的测试中不捕获异常。如果它应该抛出异常,我会用注释将其标记为异常。如果它抛出一个未经检查的异常,我会让 JUnit 为我测试失败。如果它是一个已检查的异常,我将 throws 子句添加到方法签名中,并让 JUnit 为我测试失败。