Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad practice to just throw all Exceptions in a JUnit test?

Instead of doing Exception-handling in my JUnit tests, I just declare my test-methods with ... throws Exception?

I started doing that and I don't see a reason why I should be more specific.

like image 709
codepleb Avatar asked Dec 12 '16 14:12

codepleb


2 Answers

The core aspect of unit-tests is to help you isolate / resolve bugs in your production code as quickly as possible.

In that sense: you do not write your @Test methods in order to be called by other methods. You write them so that the JUnit framework runs them.

And typically, when that test throws an exception; there is no point in catching that (unless it is expected; and you want to do further checking on that exception).

Thus: not having catch blocks; and instead adding potential throw causes to your test method signatures is the correct answer in 99.999% of all cases. Or maybe 100%; as I can't find a good counter example.

But I would be careful though about using throws Exception to quickly. You still want your code to be as "specific" as possible; so better go for throws ThatExceptionThatCanReallyBeThrown. And when that list grows too lengthy too often ... then you better follow up on that side and check if your throws list in your production code should be "trimmed" down somehow.

Edit: probably the core thing to understand is: for each any any of your tests, you have an exact expectation towards what will happen. That method should either:

  1. Not throw an exception
  2. Throw a specific exception (then you would do @Test(expected=...) thing
  3. Throw a specific exception ... which your test needs to catch for further checking
  4. Throw an exception ... which would then indicate a real "error" condition (because you didn't expect it to happen); and in that case JUnit will catch the exception and report it to you as failed testcase. (But of course, keep in mind that there is a subtle difference a testcase error and a test failure in JUnit).

And just putting throws X, Y on your test method signature is the straight forward way of addressing bullets 2 and 4.

like image 170
GhostCat Avatar answered Sep 19 '22 21:09

GhostCat


In addition to @GhostCat answer want to say - JUnit has nice feature named Rules. It is well suited for testing exceptions and maybe better than @Test(expected=Whatever.class).

Example usage:

public class Test {
  @Rule
  public final ExpectedException thrown = ExpectedException.none();

  private MyService myService;

  @Before
  public void setUp() {
    myService = new MyService ();
  }
  @Test
  public void exceptionTest() throws MyException {
    thrown.expect(MyException.class);
    thrown.expectMessage("my description");
    myService.create("bad argument"); //throws MyException("my description")
  }
}
like image 23
Sergey Morozov Avatar answered Sep 19 '22 21:09

Sergey Morozov