JUnit4 @Testexpected = MyException.classVS try / catch

问题描述

|| 我正在考虑异常处理和单元测试的最佳实践,因为我们正在尝试制定一些代码最佳实践。 在我们公司的Wiki上可以找到有关最佳做法的前一篇文章内容为“请勿使用try / catch,而应使用Junit4 @Test(expect = MyException.class)\”,而无需进一步的信息。我不相信。 我们的许多自定义异常都有一个Enum,以识别失败原因。 结果,我宁愿看到这样的测试:
@Test
public void testDoSomethingFailsBecauseZzz() {
try{
   doSomething();
} catch(OurCustomException e){
   assertEquals(\"Omg it Failed,but not like we planned\",FailureEnum.ZZZ,e.getFailure());
}
}
比:
@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   doSomething();
}
当doSomethig()看起来像:
public void doSomething throws OurCustomException {
  if(Aaa) {
     throw OurCustomException(FailureEnum.AAA);
  } 
  if(Zzz) {
     throw OurCustomException(FailureEnum.ZZZ);
  }
  // ...
}
附带说明一下,我非常相信在某些情况下@Test(expected = blabla.class)是最佳选择(例如,当异常确切且毫无疑问会导致它时)。 我是否在这里遗漏了某些东西,或者在必要时应该尝试使用try / catch?     

解决方法

         如果您只是想检查是否抛出了某种类型的异常,请使用批注的
expected
属性。 如果要检查引发的异常的属性(例如,消息或自定义成员值),请在测试中将其捕获并进行断言。 在您的情况下,您似乎想要后者(断言该异常具有某个“ 4”值);使用ѭ5没错。 您应该“不使用try / catch”(被解释为“从不”)的概括是不正确的。 杰夫是对的。您的异常层次结构的组织是可疑的。但是,您似乎认识到这一点。 :)     ,        听起来您的枚举被用作异常层次结构的替代方法?也许如果您有一个例外层次结构,则“ 6”会变得更有用吗?     ,        如果要检查原始异常类型,则使用“ 3”方法是合适的。否则,如果您需要测试有关该异常的某些信息(并且不管消息内容是常见的
enum
怪异测试),都可以进行try catch,但这有点陈旧。新的JUnit方法是使用
MethodRule
。 API中的代码(ѭ10)专门用于测试消息,但是您可以轻松查看代码并改编该实现以检查失败ѭ8。     ,        在特殊情况下,您要测试(1)是否抛出了预期的异常类型,以及(2)错误号是否正确,因为该方法可以针对不同类型抛出相同的异常。 这需要检查异常对象。但是,您可以坚持建议并验证是否抛出了正确的异常:
@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   try {
      doSomething();
   } catch (OurCustomException e) {
      if (e.getFailureEnum.equals(FailureEnum.ZZZ))  // use *your* method here
         throw e;

      fail(\"Catched OurCostomException with unexpected failure number: \" 
        + e.getFailureEnum().getValue());  // again: your enum method here
   }
}
这种模式将吞噬意外的异常并使测试失败。 编辑 更改它是因为我错过了显而易见的事情:我们可以使测试用例失败并捕获消息。所以现在:如果抛出带有预期错误代码的预期异常,则测试通过。如果由于出现意外错误而导致测试失败,则可以读取错误代码。     ,        我在搜索如何处理异常时遇到了这个问题。 如@Yishai所述,期望异常的首选方式是使用JUnit规则和
ExpectedException
。 当使用“ 14”时,如果在方法中的任何地方抛出异常,则测试方法将通过。 当您使用
ExpectedException
时:
@Test
public void testException()
{
    // If SomeException is thrown here,the test will fail.
    expectedException.expect(SomeException.class);
    // If SomeException is thrown here,the test will pass.
}
您还可以测试: 预期的消息:
ExpectedException.expectMessage()
; 预期的原因:
expectedException.expectCause()
。 附带说明:我不认为对异常消息/原因使用枚举不是一个好习惯。 (如果我错了,请纠正我。)     ,        我犯了例外,因为我和您一样面临着同样的问题,斯特夫。 使用catch-exception,您的代码可能如下所示:
@Test
public void testDoSomethingFailsBecauseZzz() {
   verifyException(myObj,OurCustomException.class).doSomething();
   assertEquals(\"Omg it failed,but not like we planned\",FailureEnum.ZZZ,((OurCustomException)caughtException()).getFailure() ;
}
    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...