Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit4 @Test(expected=MyException.class) VS try/catch

I'm pondering on exception handling and unit tests best practices because we're trying to get some code best practices in place.

A previous article regarding best practices, found on our company wiki, stated "Do not use try/catch, but use Junit4 @Test(expect=MyException.class)", without further information. I'm not convinced.

Many of our custom exception have an Enum in order to identify the failure cause. As a result, I would rather see a test like :

@Test
public void testDoSomethingFailsBecauseZzz() {
try{
   doSomething();
} catch(OurCustomException e){
   assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ, e.getFailure());
}
}

than :

@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   doSomething();
}

when doSomethig() looks like :

public void doSomething throws OurCustomException {
  if(Aaa) {
     throw OurCustomException(FailureEnum.AAA);
  } 
  if(Zzz) {
     throw OurCustomException(FailureEnum.ZZZ);
  }
  // ...
}

On a side note, I am more than convinced that on some cases @Test(expected=blabla.class) IS the best choice (for example when the exception is precise and there can be no doubt about what's causing it).

Am I missing something here or should I push the use of try/catch when necessary ?

like image 977
Stph Avatar asked Jun 15 '11 14:06

Stph


2 Answers

It sounds like your enum is being used as an alternative to an exception hierarchy? Perhaps if you had an exception hierarchy the @Test(expected=XYZ.class) would become more useful?

like image 146
Jeff Foster Avatar answered Oct 06 '22 00:10

Jeff Foster


  • If you simply want to check that an exception of a certain type was thrown, use the annotation's expected property.
  • If you want to check properties of the thrown exception (e.g. the message, or a custom member value), catch it in the test and make assertions.

In your case, it seems like you want the latter (to assert that the exception has a certain FailureEnum value); there's nothing wrong with using the try/catch.

The generalization that you should "not use try/catch" (interpreted as "never") is bunk.

Jeff is right though; the organization of your exception hierarchy is suspect. However, you seem to recognize this. :)

like image 34
Rob Hruska Avatar answered Oct 06 '22 00:10

Rob Hruska