Home > Back-end >  Junit Eclipse - No stack trace on success when exception is expected
Junit Eclipse - No stack trace on success when exception is expected

Time:10-14

I have junit tests that are using @Test(expected=) syntax. When I run those tests the exceptions are generated and the tests pass, but the exceptions' stack trace is still logged in the console.

This is confusing because there is no indication of which test generated what message. I have a lot of test and I don't know if those stack traces are just the expected exceptions or there is some problem in the test.

Is there a way to prevent tests that expect exceptions to be thrown from logging if the test succeeds?

CodePudding user response:

Yes. Don't log them. It's not JUnit printing that stuff. It's you, in your own (non-test) code. JUnit can't magically dive in there, figure out that you wrote code that explicitly tells the VM to print the trace for no good reason, and somehow suppress that.

It's not your fault, it's.. a ton of tutorials and even here on SO, answers, as well as crazy IDE defaults that led you down this path.

So, fix it! It's not too difficult; fire up your IDE's global search tool and go hunt for e.printStackTrace(). Eliminate them all. It's hunting season.

So, how would you do this? A few steps:

  1. First things first: Enter your IDE settings and fix the template when using the quick-fix of 'add try/catch'. The catch block should be throw new RuntimeException("uncaught", e);, not e.printStackTrace().

  2. Any time a method's nature inherently implies that it throws a certain checked exception, make it do so. A method named openFile that does not throws IOException is just badly written. Make it throws that, then eliminate the try/catch(Exception e) {e.printStackTrace();} which we shall henceforth name 'the dodo pattern'. That should get rid of about half of them.

  3. Next up are places where the checked exceptions you 'fixed' with the dodo pattern are not inherently part of a method's nature. For example, let's say you wrote a game save system and your current implementation works by writing it out to a DB, and you dodo-patterned the SQLException. Save games do not inherently imply DB interactions, so writing public void saveGame() throws SQLException isn't necessarily good design. The solution in pretty much all such caes is to rewrap the exception into something else. For example, make a SaveException class. Ensure it has the constructor that takes a message and a cause. Then:

} catch (SQLException e) {
  throw new SaveException("Cannot save game", e);
}

Keep the message short, sweet, don't add superfluous info (If your message involves "Something went wrong" - you're doing it wrong. It's an exception that ended up uncaught. That something is wrong is implied, no need to say it). and definitely don't add exclamation marks.

Sometimes you don't need to make an exception and can rewrap into something more useful.

  1. That leaves checked exceptions that you nevertheless doubt can actually ever really occur. Rewrap those too, into RuntimeException or some other simplistic thing, or use lombok's @SneakyThrows for these.

That should let you get rid of each and every one of those pesky .printStackTrace() calls. Once you've done that, your problem will go away.

  • Related