Unhandled Exception Junit - java

I cannot run my test because the test gets red squiggly error line in this statement decorator.decorate(new EncoderColumnDecorator()) requiring me to use either try/catch or add throws.
This is the error message.
Why do I have to put either try/catch or throws exception when I already have an attribute "expected"
My unit test:
#Test(expected=DecoratorException.class)
public void testDecorate_exception() {
decorator.decorate(new EncoderColumnDecorator()); -----Error in this line
}
Method under test
#Override
public String decorate(Object arg0) throws DecoratorException {
try{
//some code
}
}catch(Exception e){
throw new DecoratorException();
}
return arg0;
}
}

That is simply the rule that has to be followed for the code to be valid Java. If a function calls another function that throws then it must either also throw that exception or it must catch it.
It is a bit like static typing of variables. While it may seem inconvenient it can help ensure correct code by not allowing ambiguity. Having the compiler report any inconsistency helps with detecting problems much earlier.

Related

Catching versus throwing exception for unit test

In below code a checked exception is being thrown by ClassToTest.throwsException(). My preference is to add throws exception to the JUnit method signature instead of wrapping the code that throws an exception in a try catch. This preference is just based on the fact that I think its neater. Is there a coding convention I'm breaking here? Is there a difference in functionality from a testing point of view in throwing the exception versus try/catch in the testing method?
import org.junit.Test;
public class TestingClass {
#Test
public void getDataTest() throws Exception {
new ClassToTest().throwsException();
}
}
versus :
import org.junit.Test;
public class TestingClass {
#Test
public void getDataTest() {
try {
new ClassToTest().throwsException();
} catch (Exception e) {
e.printStackTrace();
}
}
}
ClassToTest.java :
public class ClassToTest {
public void throwsException() throws Exception {
}
}
If one does not expect an Exception to be thrown, there is no added benefit in adding a try-catch block to the code. Even worse, only adding a try-catch block will lead to the test passing. To make the test fail, one would have to add a call to fail() to make the test actually fail. This is a possible source for error (if one forgets to call fail()).
For completeness sake, I will talk shortly about how to verify that a certain Exception has been thrown. There are three approaches that come to my mind.
In the first attempt, one could use try-catch, but with an added fail() in the try-block, just after the calls that should throw the expected Exception. In the catch-block, one would then catch the expected Exception. All other Exceptions would be re-thrown and thus the test would fail. This has the same downsides as its sibling mentioned above.
Second, there is the JUnit4 way by annotating the test itself with #Test(expected = ExpectedException.class). This seems neat at first, but breaks the Given-When-Then structure of tests, often leading to tests looking like this:
#Test(expected = ArrayIndexOutOfBoundsException.class)
public void test() {
// GIVEN
final int[] array = new int[10];
// WHEN
final int value = array[10];
// THEN: an ArrayIndexOutOfBoundsException should be thrown
}
which is okay-ish.
Lastly, there is the JUnit5 way by wrapping the actual call into a call of assertThrows(...):
#Test(expected = ArrayIndexOutOfBoundsException.class)
void test() {
// GIVEN
final int[] array = new int[10];
// WHEN
final Exception e = assertThrows(ArrayIndexOutOfBoundsException.class,
() -> {
int value = array[10];
}
);
// THEN
assertTrue(e.getMessage().contains("10"));
}
While this still does not properly separates the WHEN from the THEN (I think this is not possible in Java), it gives the added benefit to allow checking specific parts of the Exception, e.g. the message1.
I would suggest this article over at Baelung as a further read.
1This is also possible in JUnit4, but is either done through an explicit try-catch block or through a very cumbersome mechanism that definitively breaks the Given-When-Then structure. For more information, please check the article over at Baelung mentioned above.
Simply add the throws clause to the method declaration and let the exception bubble up, as written in the JUnit4 FAQ - How do I write a test that fails when an unexpected exception is thrown?:
Declare the exception in the throws clause of the test method and don't catch the exception within the test method. Uncaught exceptions will cause the test to fail with an error.
The following is an example test that fails when the IndexOutOfBoundsException is raised:
#Test
public void testIndexOutOfBoundsExceptionNotRaised()
throws IndexOutOfBoundsException {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}
IndexOutOfBoundsException might not be a good example here, since it is a RuntimeException, but the approach is the same for other exceptions.

Test multiple lines of codes w.r.t same Exception

I have a code segment like shown below. Each line of code throw same exception. However, in practice, when first line throws an exception, testFoo finishes its job and does not continue, as expected. But, I want a bit more different thing; since they are throwing same exception, I want to continue and check these three lines w.r.t the exception which they all throw. If they throw, test should be continue.
How can I test these three line w.r.t same exception?
#test
void testFoo(){
assertNull( /*errorMessage*/, ClassFoo.foo(null)); // foo will throw `AssertionError` due to null parameter
assertNull( /*errorMessage*/, ClassBar.bar(null)); // foo will throw `AssertionError` due to null parameter
assertNull( /*errorMessage*/, ClassGbr.gbr(null)); // foo will throw `AssertionError` due to null parameter
}
Just catch the exception yourself:
#Test
void testFoo() {
boolean fooHasThrownException = false;
boolean barHasThrownException = false;
boolean gbrHasThrownException = false;
try {
ClassFoo.foo(null);
fail();
} catch (AssertionError e) {
fooHasThrownException = true;
}
try {
ClassBar.bar(null);
fail();
} catch (AssertionError e) {
barHasThrownException = true;
}
try {
ClassGbr.gbr(null);
fail();
} catch (AssertionError e) {
gbrHasThrownException = true;
}
assertThat(true, equalTo(fooHasThrownException),
equalTo(barHasThrownException),
equalTo(gbrHasThrownException));
}
Note that your assertNull() is redundant. If a method throws an exception, it will not return anything.
On the side, this is a very weird scenario to be testing. If a method throws an exception, it just seems more logical to stop any further processing, if those processes down the line are going to also throw exceptions anyway.
I have tried to implement precondition for each parameters to a method with Java built-in Assert.assertTrue...
This is not built into java, this is from junit: void junit.framework.Assert.assertTrue(...). You are confusing Java Assertions with Junit assertions.
Junit assertions should be used in your unit tests. They look like Assert.assertEquals(result, "expected result"); They are intended to test the validity of the methods under test in your unit tests.
Java assertions should be used when verifying assumptions. They look like assert param!=null:"param should not be null!"; They are part of the java language and can be turned on and off at compile time. They are intended to double check assumptions in your code and to produce zero overhead when turned off.
Programming with assertions is a great thing. Using Junit assertions outside of unit tests is dubious.
My interpretation of this question is that you are expecting an AssertFailedError in your unit test and this is meant to be part of this test. If that is the case, you can use the following junit method structure:
#Test(expected = AssertFailedError.class)
public void testFoo() throws AssertFailedError
{
assertNotNull(null);
}
You can use this when you are testing a block of code that you know will throw an exception.

Is it possible to monitor handled exceptions using JUnit?

This is what I have:
#Test
public testSendMessageToStub() {
// under the hood sends message
// if exception occurrs
// it will be catched and message will be put on retry
object.sendMessage();
}
Is there any way to mark test as failed if exception has occurred but was handled in catch block in the sendMessage() method?
Thanks
EDIT: It seems like I was too fixated on these legacy tests and how they were used, that totally missed the fact of sendMessage returning a response with a status code (!!!). So now I just assert status codes, can expand these tests into more detailed scenarios and spin them on jenkins. I would like to avoid to answer how these tests were checked previously. The thought to check for status codes came to me after reading Plux's answer. Thanks!
Exactly what you are looking for is not possible with JUnit as far as I know.
If you really would want to test this, you could store some information about the exception in the catch-block where it is handled in the sendMessage() method.
A better option, in my opinion, could be to test the output or state of the object. If the state/output is exactly the same as when an exception doesn't occur, then whats the point of testing it? Do you have an overly broad catch-block?
EDIT: To AdityaTS, I dont have enough reputation to comment on a post, but my comment: you have not supplied all the code, so I can not say for sure, but my guess is that its the Logger.getLogger IN the catch-block that casts the ClassNotFoundException. (Either that or loadConnectionInfo()) see http://docs.oracle.com/javase/7/docs/api/java/lang/ClassNotFoundException.html
You cannot do this without modifying sendMessage method. If for example you catch the exception there but choose to ignore it and just return some value, code outside of the method doesn't know it. You can get around this by refactoring the code of object: move the code that handles the exception to a separate method, called e.g. handleException. Then, in your test you can create a subclass where handleException will execute the original handleException from superclass, but additionally set some flag which you will be able to read in your test and in this way tell that the exception was thrown. However, if you cannot modify the code for object's class, I'm afraid you're out of luck.
So you expect the exception to propagate out of the sendMessage() method, right?
This is another way to write a test that verifies an exception you expect will be thrown.
#Test (expected = MyExpectedException.class)
public testSendMessageToStub() {
// under the hood sends message
// if exception occurrs
// it will be catched and message will be put on retry
object.sendMessage();
}
And it's usually best to be as specific as possible (e.g. MyExpectedException.class over Exception.class)
The exception generated in the sendMessage() class will be available in the test method. Add a try catch block around the sendMessage() method like this
#Test
public testSendMessageToStub() {
try
{
object.sendMehssage();
}
catch(Excpetion e) //Use more specific exception type if you know
{
fail(e.getMessage());
}
}
I have tried this in my code. It worked for me. Let me know.
public DBConnectionInfo connectionInit()
{
loadConnectionInfo();
try
{
Class.forName(dbObject.getDriver());
} catch (Exception e)
{
Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
lgr.log(Level.SEVERE, e.getMessage(), e);
}
try
{
dbObject.setConnection(DriverManager.getConnection(dbObject.getDatabaseURL(), dbObject.getUserName(),
dbObject.getPassword()));
} catch (Exception e)
{
Logger lgr = Logger.getLogger(PostgreLocationManager.class.getName());
lgr.log(Level.SEVERE, e.getMessage(), e);
}
return dbObject;
}
The test case for the above class.
#Test
public void testDriverFailure()
{
when(dbModelObject.getDriver()).thenReturn("driver");
when(dbModelObject.getDatabaseURL()).thenReturn("jdbc:postgresql://127.0.0.1:5432/testdb");
when(dbModelObject.getUserName()).thenReturn("postgres");
when(dbModelObject.getPassword()).thenReturn("postgres");
try
{
dbConnector.connectionInit();
} catch (Exception e)
{
assertTrue(e instanceof ClassNotFoundException);
}
verify(dbModelObject).getDriver();
}

What does it mean when the main method throws an exception?

I'm reviewing a midterm I did in preparation for my final exam tomorrow morning. I got this question wrong, but there's no correct answer pointed out, and I neglected to ask the prof about it.
Consider the following code snippet:
public static void main(String[] args) throws FileNotFoundException
Which of the following statements about this code is correct?
The main method is designed to catch and handle all types of exceptions.
The main method is designed to catch and handle the FileNotFoundException.
The main method should simply terminate if the FileNotFoundException occurs.
The main method should simply terminate if any exception occurs.
I had chosen the second option.
Answer is number 4,
4.- The main method should simply terminate if any exception occurs.
The throws clause only states that the method throws a checked FileNotFoundException and the calling method should catch or rethrow it. If a non-checked exception is thrown (and not catch) in the main method, it will also terminate.
Check this test:
public class ExceptionThrownTest {
#Test
public void testingExceptions() {
try {
ExceptionThrownTest.main(new String[] {});
} catch (Throwable e) {
assertTrue(e instanceof RuntimeException);
}
}
public static void main(String[] args) throws FileNotFoundException {
dangerousMethod();
// Won't be executed because RuntimeException thrown
unreachableMethod();
}
private static void dangerousMethod() {
throw new RuntimeException();
}
private static void unreachableMethod() {
System.out.println("Won't execute");
}
}
As you can see, if I throw a RuntimeException the method will terminate even if the exception thrown is not a FileNotFoundException
Dude, a little late, but answer is Number 3.
Number 1 is false because it is not handling FileNotFoundException
Number 2 is false for the same reason.
Number 3 is true. If a FileNotFoundException is thrown, the main method will terminate.
Number 4 is false. It would not terminate in case of ANY exception. It would terminate only in case of unchecked exception or FileNotFoundException. If there are not other checked exceptions declared in the 'throws' clause, it means they are being handled within the method.
The main method is not catching any exceptions, instead it handles the FileNotFoundException by throwing it to the source which invoked the main method.
The system runtime launches the JVM classes, one specific class among the JVM classes invokes the main method.
The handling for the main method's throws is at the mercy of the JVM classes in that case.
You can read about it in the Java language specification provided by Oracle.
Additionally you can view the source code for some of the JVMs available out there, going that path though takes you away to other programming languages,OpenJdk.
I thought of sharing my small humbled research crust in that topic, hope it helps curious ones :)
I agree with some other answers that the correct answer to the question is option 3. Option 4 says:
The main method should simply terminate if any exception occurs.
Note the "any" in this option. Here's an example of code in which an exception occurs, but main() does not terminate:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsACheckedException();
} catch (SomeCheckedException e) {
// do something to handle this exception
}
}
In this code an exception occurs, but the method does not terminate, as it's been setup to handle this exception. If the exception were an uncaught UncheckedException, then the method would terminate, of course. The point of option 4, though, is that any counter-example invalidates it, since it says "any" exception occurs.
Option 3, however, limits this termination to only occur when the exception in the method's signature is thrown:
The main method should simply terminate if the FileNotFoundException occurs.
The reason option 3 makes more sense is because code like the following does not make sense in practice:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsFileNotFoundException();
} catch (FileNotFoundException e) {
// do something to handle this exception
}
}
It doesn't make much sense to declare that a method throws an exception, but catch that exception in the method (unless, perhaps, you re-throw it after doing something, in which case option 3 still holds, as the method terminates eventually).
With only the declaration of main(), it is impossible to say which answer is objectively correct. Any of the statements could be true, depending on the definition of the method.
The main method is designed to catch and handle all types of exceptions.
The main method is designed to catch and handle the FileNotFoundException.
Both of the above statements are true of the following:
public static void main(String[] args) throws FileNotFoundException {
while (true) {
try {
doSomething();
}
catch (Exception e) {}
}
}
The declared exception is never thrown by main(), but that is not an error; just pointless and misleading.
The main method should simply terminate if the FileNotFoundException occurs.
The main method should simply terminate if any exception occurs.
Both of the above statements are true of the following:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (Exception e) {
return;
}
}
Of course, we can guess at the intention of the question based on what a decent and reasonable programmer might intend to communicate with this method signature. Which would be that they intend for the method to throw FileNotFoundException, and necessarily handle other checked Exceptions. We can also reasonably assume that "handle" does not just mean "process", but specifically that it will not (re-)throw such an exception.
These assumptions immediately rule out #1 and #2.
The remaining question is whether "simply terminate" includes throwing an exception, or only an explicit return/System.exit(). In the former case, both of #3 and #4 could still be true:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (FileNotFoundException fnfe) {
throw fnfe;
}
catch (Exception e) {
return;
}
}
In the latter case, neither #3 nor #4 can be true while also satisfying the assumption that main() will throw FileNotFoundException.
In sum, the options are not worded well. If I had to pick an answer, it would be #3 based on the logic of MartinV's answer. My assumption would be that the word "should" in #3 was an unfortunate choice by the professor, and that something like "may" would have been a better option. It would also have been a good idea to use more precise language than "simply terminate" (and, arguably, "handle").
The answer is both 2 & 3.
2.The main method is designed to catch and handle the FileNotFoundException.
3.The main method should simply terminate if the FileNotFoundException occurs.
But if fails to handle the exception even though it is designed to handle it and the programs gets terminated abnormally.
throws keywords is used to make JVM handle the exceptions which we are lazy to handle, it compiles successfully but shows the exception during runtime(if u handle it in main method then it compiles and runs successfully).
4.The main method should simply terminate if any exception occurs.
Is not correct always because the exceptions which occurs may be handle in the main method.
1.The main method is designed to catch and handle all types of exceptions.Is incorrect as JVM doesn't handle unchecked exceptions.

Wrap exceptions by runtime exceptions with an annotation

Is there a way to annotate a method so all exceptions thrown are converted to runtime exception automagically?
#MagicAnnotation
// no throws clause!
void foo()
{
throw new Exception("bar")'
}
Project Lombok's #SneakyThrows is probably what you are looking for. Is not really wrapping your exception (because it can be a problem in a lot of cases), it just doesn't throw an error during compilation.
#SneakyThrows
void foo() {
throw new Exception("bar")'
}
You can do this with AspectJ. You declare a joinpoint (in this case invocation of the method foo) and 'soften' the exception.
Edit To elaborate a bit on this:
Say you have the following class Bar:
public class Bar {
public void foo() throws Exception {
}
}
...and you have a test like this:
import junit.framework.TestCase;
public class BarTest extends TestCase {
public void testTestFoo() {
new Bar().foo();
}
}
Then obviously the test is not going to compile. It will give an error:
Unhandled exception type Exception BarTest.java(line 6)
Now to overcome this with AspectJ, you write a very simple aspect:
public aspect SoftenExceptionsInTestCode {
pointcut inTestCode() : execution(void *Test.test*());
declare soft : Exception : inTestCode();
}
The aspect basically says that any code from within a Test (i.e.: a method that starts with "test" in a class that ends in "Test" and returns 'void') that throws an exception should be accepted by the AspectJ compiler. If an exception occurs, it will be wrapped and thrown as a RuntimeException by the AspectJ compiler.
Indeed, if you run this test as part of an AspectJ project from within Eclipse (with AJDT installed) then the test will succeed, whereas without the aspect it won't even compile.
No way to do that, at least for now I use workaround like this (simplified):
#SuppressWarnings({"rawtypes", "unchecked"})
public class Unchecked {
public static interface UncheckedDefinitions{
InputStream openStream();
String readLine();
...
}
private static Class proxyClass = Proxy.getProxyClass(Unchecked.class.getClassLoader(), UncheckedDefinitions.class);
public static UncheckedDefinitions unchecked(final Object target){
try{
return (UncheckedDefinitions) proxyClass.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler(){
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (target instanceof Class){
return MethodUtils.invokeExactStaticMethod((Class) target, method.getName(), args);
}
return MethodUtils.invokeExactMethod(target, method.getName(), args);
}
});
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
And the usage looks like:
import static ....Unchecked.*;
...
Writer w = ...;
unchecked(w).write(str, off, len);
The trick is that interface is "never finished" and everytime I need unchecked method somewhere, I'll wrap that object into unchecked and let IDE generate method signature in interface.
Implementation is then generic (reflective and "slow" but usually fast enough)
There are some code post-processors and bytecode-weavers but this was not possible (not even aop or other jvm based language) for my current project, so this was "invented".
I think it is possible with bytecode re-engineering, customized compiler or perhaps aspect oriented programming1. In the contrary to Java, C# has only unchecked exceptions2.
May I ask why you want to suppress the checked exceptions?
1 according to Maarten Winkels this is possible.
2 and they are thinking about introducing checked ones, according to some Channel 9 videos.
Edit: For the question: It is possible in the sense that you can annotate your methods to flag them to be a candidate for checked exception suppression. Then you use some compile time or runtime trick to apply the actual suppression / wrapping.
However, as I don't see the environment around your case, wrapping an exception in these ways might confuse the clients of that method - they might not be prepared to deal with a RuntimeException. For example: the method throws an IOException and your clients catches it as FileNotFoundException to display an error dialog. However if you wrap your exception into a RuntimeException, the error dialog gets never shown and probably it kills the caller thread too. (IMHO).
The Checked exceptions are responsability of the method implementation.
Take very very carefully this fact. if you can do not use workaround artifacts like that.
You can do this in any case via use of the fact that Class.newInstance does not wrap an Exception thrown by the no-arg constructor in an InvocationTargetException; rather it throws it silently:
class ExUtil {
public static void throwSilent(Exception e) { //NOTICE NO THROWS CLAUSE
tl.set(e);
SilentThrower.class.newInstance(); //throws silently
}
private static ThreadLocal<Exception> tl = new ThreadLocal<Exception>();
private static class SilentThrower {
SilentThrower() throws Exception {
Exception e = tl.get();
tl.remove();
throw e;
}
}
}
Then you can use this utility anywhere:
ExUtil.throwSilent(new Exception());
//or
try {
ioMethod();
} catch (IOException e) { ExUtil.throwSilent(e); }
By the way, this is a really bad idea :-)
I use the completion / template system of Eclipse to wrap any block of code easily.
Here is my template :
try { // Wrapp exceptions
${line_selection}${cursor}
} catch (RuntimeException e) { // Forward runtime exception
throw e;
} catch (Exception e) { // Wrap into runtime exception
throw new RuntimeException(
"Exception wrapped in #${enclosing_method}",
e);
}

Categories