JUnit handling of RuntimeException (specifically) - java

I tend to throw as many checked Exceptions up as possible: it declutters the code (and I regard checked Exceptions as a dubious aspect of Java). I tend to use them when "refining" code.. i.e. when it makes sense for the particular context.
This approach gets slightly complicated when overriding superclass/interface methods which don't throw the requisite Exception, and therefore I tend to do this:
#Override
public void close() {
try {
_close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
where _close is a private method which does all the business.
The problem when it comes to JUnit, if you actually want to test something where an exception is thrown by _close() is that the resulting RuntimeException seems to be handled by JUnit in an "unconditional" way: it seems always to stop the test with a failure message... even if you actually catch and deal with it in a try .. catch!
There is a sort of "workaround" for this which I've found (the CUT class closes all its closeableComponents when it is closed):
#Test (expected = RuntimeException.class)
public void errorFlagShouldBeSetIfAnyCloseablesThrowExceptionWhenCUTCloses() throws Exception {
Closeable spyCloseable = spy( new Closeable(){
#Override
public void close() throws IOException {
throw new IOException( "dummy" );
}});
spyCUT.addCloseableComponent( spyCloseable );
Exception blob = null;
try{
spyCUT.close();
}catch( Exception e ){
blob = e;
}
assertThat( spyCUT.getErrorFlag() ).isTrue();
if( blob != null ){
throw blob;
}
I.e. if you don't have this expected setting you always get a test failure (because of the RuntimeException "ignoring" the try .. catch). But in order to satisfy the expected you then have to rethrow the RuntimeException at the end of the test...
... is there any way of varying JUnit's handling of RuntimeExceptions?

Something must be wrong in your setup. JUnit does not have any such special handling for runtime exceptions.
I put together this MCVE; and it passes.
static class CUT {
void close(Closeable _close) {
try {
_close.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
#Test
public void test() throws Exception {
Closeable spyCloseable = Mockito.spy(new Closeable() {
#Override
public void close() throws IOException {
throw new IOException("dummy");
}
});
Exception blob = null;
try {
new CUT().close(spyCloseable);
fail("should have thrown");
} catch (Exception e) {
blob = e;
}
assertThat(blob.getMessage(), is("java.io.IOException: dummy"));
}
It is not exactly what you have up there; but "close enough" in my mind.
Long story short: your answer is coming from some other place. I suggest: do the same as I did: create a true mcve; and work your way from there!

Related

Mock void method's try catch block and catch exception using EasyMock or Mockito

I have a code something like this and I want to write a unit test to below code, completely . I am able to hit try part of the code but couldn't figure out how I can test the catch exception part.
public class CacheUpdateTask implements Runnable {
private WarehouseCache cache;
private static final int EXPONENTIAL_MULTIPLIER = 100;
private static final int MAXIMUM_TIME_LIMIT = 5;
public CacheUpdateTask(
final WarehouseCache cache) {
this.cache = cache;
}
#Override
public void run() {
LOG.info("Requesting warehouse mapping from AService and updating the cache.");
final Callable<Void> updateCache =
new Callable<Void>() {
#Override
public Void call() throws Exception {
cache.updateWarehouseCountryCodeCache();
return null;
}
};
final Retryer<Void> retryer = RetryerBuilder.<Void>newBuilder()
.retryIfException()
.withWaitStrategy(WaitStrategies.exponentialWait(EXPONENTIAL_MULTIPLIER, MAXIMUM_TIME_LIMIT,
TimeUnit.MINUTES))
.withStopStrategy(StopStrategies.neverStop())
.build();
try {
retryer.call(updateCache); // this is also a void method, so no return here
} catch (ExecutionException | RetryException e) {
e.printStackTrace();
LOG.error(e);
LOG.error("Exception when refreshing the cache.");
}
LOG.info("Cache has been updated.");
}
}
Points to note
Here the retryer is configured to neverStop. Whenever an exception is raised on call retryer.call(updateCache); retryer actually retries. So in try block when retryer.call(updateCache) throws an exception, execution doesn't flow to catch block and just keeps trying.
I tried to mimic code in try block to throw some exception in multiple ways, but it is never invoking the code in catch. Below code is my last attempt before creating this question. In most of my attempts tests are succeeding but I am never ending up testing the catch block
Below code runs successfully, but it is actually not hitting catch block based on code coverage test.
#Test (expected = ExecutionException.class)
public void test_UpdateCacheFOServiceRunException() throws Exception {
WarehouseCacheFOServiceUpdateTask mockUpdateTaskFOService;
WarehouseCache mockClientCache;
mockUpdateTaskFOService = Mockito.mock(WarehouseCacheFOServiceUpdateTask.class);
mockClientCache = Mockito.mock(WarehouseCache.class);
Mockito.doThrow(ExecutionException.class)
.when(mockClientCache).updateWarehouseCountryCodeCacheFOService();
//clientCache.updateWarehouseCountryCodeCacheFOService();
//Mockito.doThrow( ExecutionException.class )
// .when(mockUpdateTaskFOService).run();
mockClientCache.updateWarehouseCountryCodeCacheFOService();
mockUpdateTaskFOService.run();
}
Your test is incorrect to expect this
#Test(expected = ExecutionException.class)
If you look back at your code, you will see that you catch, log and swallow that exception. It is never rethrown, so your test should not expect it.
Other than that, your test looks broadly correct. You have no means to make any meaningful assertions, since the logger is static.
The following is a bit misleading
Mockito.doThrow(ExecutionException.class)
since the ExecutionException you are trying to catch an exception which Retryer is supposed to wrap the original exception with. What you are currently simulating is an ExecutionException wrapping an ExecutionException. It will work for the sake of your test, but is not realistic. I would throw a generic Exception.class (which will then be wrapped).
There is a slight bug in your code which will cause misleading logging. This line will execute even if an exception was thrown, caught, and logged.
LOG.info("Cache has been updated.");
You have two choices, you can either put a return in the catch, or move the logging line.
try {
retryer.call(updateCache);
LOG.info("Cache has been updated."); // this
} catch (ExecutionException | RetryException e) {
e.printStackTrace();
LOG.error(e);
LOG.error("Exception when refreshing the cache.");
return; // or this
}

Determining which method throws exception

Below code catches an IOException , the first exception throw will be the one that is caught. To determine which method is throwing the IOException is the sole solution to wrap each method that throws an IOException in a try catch block ? I ask as my planned solution adds alot of try catch code and perhaps there is a cleaner solution to determine which method is throwing IOException ?
import java.io.IOException;
import java.net.SocketException;
public class Driver {
private static void te() throws IOException {
throw new java.net.SocketException("Connection Reset");
}
private static void te2() throws IOException {
throw new java.net.SocketException("Connection Reset 2");
}
private static void te3() throws IOException {
throw new java.net.SocketException("Connection Reset 3");
}
public static void main(String args[]) {
try {
Driver.te();
Driver.te2();
Driver.te3();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The answer depends on your required logic. If the treatment of your exception is supposed to be different depending on which method threw the exception, (meaning that within catch you will need to write different error handling code depending on which method threw the exception, then you do need to wrap each method invocation into separate try-catch. But if the error handling is the same then your code is fine (except that usually, you print your stacktrace into a log file) and you would be able to figure out which method threw the exception by reading your stacktrace as a human user. But then again if the error handling is the same then your code doesn't need to know which specific method threw the exception.
I don't know why you are doing something like that, and surely a real situation would be far away from this code fragment but, in "real life" I would consider extending IOException: so you will have a single try with three catches in the main method. Do you like this solution?
Create a custom exception for each method:
class TeException extends IOException { /* constructor */ }
private static void te() throws TeException {
throw new java.net.SocketException("Connection Reset");
}
Then it is fairly easy to distinguish among multiple exception with separate catch blocks:
try {
Driver.te();
Driver.te2();
Driver.te3();
} catch (TeException e) {
e.printStackTrace();
} catch (Te2Exception e) {
e.printStackTrace();
} catch (Te3Exception e) {
e.printStackTrace();
}
An alternative might be to read the method that failed with the stacktrace:
final String failedMethodName = e.getStackTrace()[0].getMethodName());
You can do it as follows:
try {
Main.te();
Main.te2();
Main.te3();
} catch (Exception e) {
System.out.println(e.getStackTrace()[0].getMethodName());
}
In a real life scenario, you would probably be writing something to a log file in the case of an exception. For example:
public class Driver {
// assuming slf4j
private static Logger logger = LoggerFactory.getLogger(Driver.class);
private static void te() throws IOException {
logger.error("exception happened in te()");
throw new java.net.SocketException("Connection Reset");
}
}
Then, to figure out which methods threw exceptions, you would only need to open the log file and check.

How to handle Exception properly from a method?

Suppose, I have a method:
private void someMethod() {
try {
//Do something here
}
catch (NullPointerException ex) {
System.out.println("error");
}
}
Now, I want to use this method somewhere else:
private void newMethod() {
someMethod();
JOptionPane.showMessageDialog(null, "Exception didn't occur");
}
Now, I want that if exception occurs in someMethod(), then newMethod() will not advance further, I mean, the JOptionPane message will not be shown in this case.
What will be the best way to do that? I have found a way by throwing another NullPointerException in catch block of someMethod() and then handling that from newMethod(). The code below demonstrates that:
private void someMethod() {
try {
//Do something here
}
catch (NullPointerException ex) {
System.out.println("error");
throw new NullPointerException("error");
}
}
private void newMethod() {
try {
someMethod();
JOptionPane.showMessageDialog(null, "Exception didn't occur");
}
catch (NullPointerException ex) {
System.out.println("error");
}
}
But, by this method, I am facing some difficulties for other cases. I guess there are better ways to achieve that. Thanks anyway.
You don't need to handle the exception inside someMethod. Instead you can declare the exception in this method's throws clause (if it is a checked exception) and let newMethod handle it.
private void someMethod() throws SomeCheckedException {
//Do something here
}
In case of NullPointerException, you don't need to do above, as it is an unchecked exception. Don't catch it inside someMethod, instead have try-catch inside newMethod.
It is good practice if your function intend to throw exception make it part of function declaration. So recommendation is to change someMethod() to private void someMethod() throws <exception Name>.
Depends on your requirement you can handle the exception in same method and throw another exception, or re throw same exception and handle it in another function.
In case you are re-throwing the same exception syntax is as follows:
private void someMethod() throws WhateverException {
try {
//Do something here
}
catch (WhateverException e) {
throw e;
}
}

Issue with Exception type handling when not throwing them - wanting a more generic version of multi-catch

Sorry for the TL;DR, but I feel like it needs some explanation or it will be misunderstood.
I have a method that makes a call to (generally external) code which I expect to sometimes throw a RuntimeException, and uses futures which can throw InterruptedException or ExecutionException, and I want to be able to return an ordered set of returned values to from the call up until the exception was thrown, and the exception that was thrown. I wrote something that works, but unfortunately, the way the code looks makes me feel like I'm doing something wrong. What I think I really want is multi-catch to be a more generic concept that. That would allow pretty clean code to solve it, kind of like this:
public class SomeResults {
private final Set<SomeReturnType> valuesReturned;
private final #Nullable RuntimeException | ExecutionException | InterruptedException exception;
public SomeResults(Set<SomeReturnType> valuesReturned, RuntimeException | ExecutionException exception {
this.valuesReturned = valuesReturned;
this.exception = exception;
}
public Set<SomeReturnType> getValuesReturned() {
return valuesReturned;
}
public #Nullable RuntimeException | ExecutionException | InterruptedException getException();
}
And have a method that wraps up making the calls to the external code
...
generateResults(Bar bar) {
// Setup code
Set<SomeReturnType> valuesReturned = new LinkedHashSet<>();
...
// loop
{
// stuff
... // exceptions in this method should throw except for this one external code call
try {
valuesReturned.add(externalCodeCallGetSomeReturnValue(bar))
}
catch( RuntimeException | ExecutionException | InterruptedException e) {
return new MyResults(valuesReturned, e)
}
...
}
return new MyResults(valuesReturned, (RuntimeException | ExecutionException | InterruptedException) null);
}
And subsequently do
SomeResults myResults = foo.generateResults(new Bar());
if(myResults.getException() != null) {
throw(myResults.getException);
}
Etc. Note that I do note always want to immediately rethrow the exception - it depends on who is using these results what they will want to do with them. I might do something like
try {
SomeResults myResults = foo.generateResults(new Bar());
Foobar Foobar = new Foobar(myResults);
}
catch(Exception e) {
// I don't want to see any exceptions from externalCodeCallGetSomeReturnValue(bar) here
...
}
Of course, I could let the exception get thrown in the function that generates results, instead of catching the exception and returning it as a result. This has two pretty big issues:
1. Now returning the set of values is going to be awkward - I could perhaps pass in a Set to the method that needs to "return" results and it modifies that set instead of returning a set. That allows the set to be up to date when the exception is returned. Eg
generateResults(Bar bar, Set<SomeReturnType> orderedListForMeToWrite) throws ExecutionException, InterruptedException
What if code surrounding the external method call throws a runtime exception? Now I have no easy way of distinguishing if the exception call was from the actual call to the external code, or something else! I actually ran into this issue when attempting this design. The code threw IllegalArgumentException from somewhere else, and my code handling treated it as if it had been thrown from SomeReturnType externalCodeCallGetSomeReturnValue(Bar bar). This seemed like a code health issue, which is why I moved away from this solution.
The solution I went with is to just store the exception as an Exception. However, I hated losing that type information. With no additional code work, if something wanted to throw it, it will have to declare "throws Exception", which is not good, similar code health issues there. Is there a good way to handle this situation?
What I ended up doing to get it to work the way I wanted it to is as follows:
public static class SomeResults {
private final Set<SomeReturnType> orderedReturnValues;
private final #Nullable Exception exception;
AsyncEchoesResult(Set<SomeReturnType> responses) {
this.orderedResponses = responses;
this.exception = null;
}
AsyncEchoesResult(Set<SomeReturnType> responses, RuntimeException exception) {
this.orderedResponses = responses;
this.exception = exception;
}
AsyncEchoesResult(Set<SomeReturnType> responses, ExecutionException exception) {
this.orderedResponses = responses;
this.exception = exception;
}
AsyncEchoesResult(Set<SomeReturnType> responses, InterruptedException exception) {
this.orderedResponses = responses;
this.exception = exception;
}
public Set<SomeReturnType> getResponses() {
return orderedResponses;
}
public #Nullable Exception getException() {
return exception;
}
public void throwExceptionIfExists() throws ExecutionException, InterruptedException {
try {
throw (exception);
}
catch (RuntimeException | ExecutionException | InterruptedException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException("Unexpected exception type in SomeResults",e);
}
}
}
Obviously, this is pretty ugly. If I hate the constructors as they are I can easily enough replace them with a single one that takes an Exception, but that weakening the type-checking to only the runtime call of throwException(). Anyway, are there alternatives that work better? Note that I'm using with JDK 7 so while JDK 8 answers would be interesting, that won't fix it for what I'm working on.
Since Java doesn’t allow declare a variable as “one of these types” you have to encapsulate the exception using the only construct which supports such a type set: a piece of code throwing that exception.
Consider the following type definitions:
interface ReThrower {
void reThrow() throws RuntimeException, ExecutionException, InterruptedException;
}
static class MyResult
{
private final Set<SomeReturnType> valuesReturned;
private final #Nullable ReThrower exception;
public MyResult(Set<SomeReturnType> valuesReturned, ReThrower exception) {
this.valuesReturned = valuesReturned;
this.exception = exception;
}
public Set<SomeReturnType> getValuesReturned() {
return valuesReturned;
}
public void reThrowException()
throws RuntimeException, ExecutionException, InterruptedException
{
if(exception!=null) exception.reThrow();
}
}
Then you can create a MyResult like this:
MyResult generateResults(Bar bar) {
// Setup code
Set<SomeReturnType> valuesReturned = new LinkedHashSet<>();
// …
// loop
{
// stuff
// … exceptions in this method should throw except for this one external code call
try {
valuesReturned.add(externalCodeCallGetSomeReturnValue(bar));
}
catch( RuntimeException | ExecutionException | InterruptedException e) {
// In Java 8 you would say: new MyResult(valuesReturned, ()->{ throw e });
return new MyResult(valuesReturned, new ReThrower() {
public void reThrow()
throws RuntimeException, ExecutionException, InterruptedException {
throw e;
}
});
}
//...
}
return new MyResult(valuesReturned, null);
}
Note that the inner class (or lambda expression in Java 8) implicitly stores the exception and that that implicit variable has the desired “one of the listed exception type”. Then, you can safely re-throw the exception:
MyResult results = new MultiCatchAndStore().generateResults(new Bar());
try
{
results.reThrowException();
} catch(RuntimeException | ExecutionException | InterruptedException ex)
{
// handle, of course, you could also have separate catch clauses here
}

Exception already caught error

Here's the code:
public class Exc {
int x = 2;
public void throwE(int p) throws Excp, Excp2 {
if(x==p) {
throw new Excp();
}
else if(x==(p+2)) {
throw new Excp2();
}
}
}
Here's the handler code:
public class tdExc {
public static void main(String[] args) {
Exc testObj = new Exc();
try {
testObj.throwE(0);
System.out.println("This will never be printed, so sad...");
} catch(Exception Excp) {
System.out.println("Caught ya!");
} catch(Exception Excp2) {
System.out.println("Caught ya! Again!!!!");
} finally {
System.out.println("This will always be printed!");
}
}
}
Excp and Excp2 both extends Exception and have similar code(nothing). Now I'm getting the error Exception has already been caught error at Excp2, regardless of whether I supply 2 or 0 to throwE method.
You're looking for:
try
{ }
catch(Excp excp)
{
log(excp);
}
catch(Excp2 excp2)
{
log(excp2);
}
finally
{ }
When you catch an exception, to specify the type of the exception, and the name of of its reference.
Your original code tried to catch Exception, which is the least specific exception, so you cannot catch anything after that.
When you are catching an exception, you have to specify what type of exception you are catching, this will allow you to better handle the exception that has occured. One thing that you have to keep in mind though, is that there is that there are specific and other more "wide purpose" exceptions.
For instance, NumberFormatException is more specific than Exception, since NumberFormatException will be thrown whenever you will try to parse a string into a number.
Thus, when having multiple catch statements, always put the most specific one on top, and the more generic ones at the end. If you put the more generic ones at the beginning, they will catch the exception before it can be passed to a more specific catch statement.
In your case, you are trying to catch the same exception twice, since you have two catch statements that try to catch the same exception.
Java dispatches to the catch() clauses based on the types of the exception: your clauses are both trying to catch an exception of type Exception, and give them the names Excp and Excp2:
public class tdExc {
public static void main(String[] args) {
Exc testObj = new Exc();
try {
testObj.throwE(0);
System.out.println("This will never be printed, so sad...");
} catch(Exception Excp) {
Shouldn't this be Excp e?
System.out.println("Caught ya!");
} catch(Exception Excp2) {
Shouldn't this be Excp2 e?
System.out.println("Caught ya! Again!!!!");
} finally {
System.out.println("This will always be printed!");
}
}
}
And, while it's unrelated, I think your earlier code would be easier for you to think about if you write it more like this:
public void throwE(boolean p) throws Excp, Excp2 {
if(p) {
throw new Excp();
} else {
throw new Excp2();
}
}
Call it with true or false as parameters.
I believe the exception can only be caught once with java. The first exception handler will process the error.
Please someone tel me if this is true for java :)

Categories

Resources