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:
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);
, note.printStackTrace()
.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 notthrows IOException
is just badly written. Make it throws that, then eliminate thetry/catch(Exception e) {e.printStackTrace();}
which we shall henceforth name 'the dodo pattern'. That should get rid of about half of them.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 writingpublic 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 aSaveException
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.
- 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.