how to execute catch block for code coverage in mockito? - springmockito

i am tying to execute catch block in order to achieve 90% sonar coverage. Here is the code
public Map<Integer, Triplet<Integer, Integer, Integer>> getResult(int num1, List<Integer> numbers) {
List<Triplet<Integer, Integer, Integer>> result;
try {
result = innerMethod(Util.getRes(num1), num1, numbers);
return result;
}
}
i tried the below approach,
public void ExcepTest(){
//Tried method 1
when(mockObj.getResult(anyInt(),anyList())).thenThrow(mock(Exception.class));
//Tried method 2
doThrow(new RuntimeException()).when(mockObj).getResult(anyInt(),anyList());
//Tried method 3
doThrow(new RuntimeException()).when(mockObj.getResult(anyInt(),anyList()));
}
it throws invocationTaget exception instead going to that catch block. And in that innerMethod some DB connections are there with try-catch block.
How to execute that catch block? Can anyone help me on this?

Related

Handling Runtime Exception in CompletableFuture in java8

Below is the sample code I'm using to understand exception handling in completablefuture in java8.
If we make use of exceptionally method as per doc,
exceptionally method catches even runtime exception as well and proceeds to last block in the pipeline.
if we don't use exceptionally method then, it justs prints running and exits.
Correct me if my understanding isn't correct.
Question is Lets say if i want to throw runtime exception and want application to stop. Basically if i throw Runtime exception , it shouldn't proceed to next block in pipeline. How should i do that. Any pointers are helpful.
public static void main(String[] args) {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if(i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).exceptionally(it -> {
System.out.println(it.getMessage());
return "empty";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
}
Try this:
public static void main(String[] args) {
try {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if (i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).exceptionally(it -> {
if (it.getMessage().contains("ding")) {
throw (RuntimeException) it;
}
System.out.println(it.getMessage());
return "empty";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
retrieveName.join();
} catch (Exception e) {
System.out.println("main() exception, cause=" + e.getCause());
}
}
This is the output:
running
main() exception, cause=java.lang.RuntimeException: ding
I made 3 small changes to your code:
Wrapped it all in a try-catch
Threw a RuntimeException in exceptionally() for the "ding" exception.
Added a call to retrieveName.join(). From the Javadoc for CompletableFuture.join():
public T join​()
Returns the result value when complete, or throws an (unchecked) exception if completed exceptionally.
Update based on OP feedback ------->
Lets say if i want to throw runtime exception and want application to
stop. Basically if i throw Runtime exception , it shouldn't proceed to
next block in pipeline. How should i do that.
You can achieve what you want with just 2 changes to your code:
[1] Completely remove the exceptionally() callback so the CompletableFuture (CF) terminates with an exception. In exceptionally() in the OP code the exception was being swallowed rather than rethrown, and returning a CF, so the thenApply() method was still performed.
[2] Add a call to retrieveName.join() at the end of main(). This is a blocking call, but since the thread had terminated with an exception that 's not really relevant for the sample code. The join() method will extract the thrown RunTimeException and re-throw it, wrapped in a CompletionException.
Here's your modified code:
public static void main(String[] args) {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if(i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
retrieveName.join();
}
Notes:
This is not how to do things in Production. The blocking call from join() was not a problem here, but could be for a long running CF. But you obviously can't extract the exception from the CF until it is complete, so it makes sense that the join() call blocks.
Always bear in mind that main() is not running in the same thread(s) as the CF.
An alternative approach (if viable) might be to handle all the necessary post-exception actions (logging, etc,) within exceptionally() and then terminate normally with a suitable return value (e.g. "Exception handled!") rather than propagating the exception.
You can check whether the CF is still running by calling the non-blocking isDone() method. You can also check whether the CF ended with an exception (isCompletedExceptionally()) or was cancelled(isCancelled​()).

Junit test for Exception

I try to test my Exception JUnit and the test doesn't pass I have this error trace :
org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnitAndHigherRunnerImpl.java:37)
and
org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
and here is my code :
PatientEntityFacade pef = new PatientEntityFacade();
Mockito.when(pef.findByNumber(5555)).thenReturn(patientEntity);
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
public void shouldThrow() throws PatientNotFoundException
{
thrown.expect(PatientNotFoundException.class);
thrown.expectMessage("personalized exception no patient found");
try {
pef.findByNumber(5555);
} catch (com.patient.facade.PatientNotFoundException e) {
e.printStackTrace();
}
}
If you watn to test your Exception, then do it the right way.
Define when Exception should be thrown.
in #BeforeClass if every Method should
in #Test-method if only this Method should throw it.
Notice, that you can use any(X.class) if other methods got other values for it.
Don´t try-catch in unit-tests.
Catch it this way and if there is no Exception, the test will fail.
#Test(expected = PatientNotFoundException.class)
public void shouldThrow()
pef.findByNumber(5555);
}

test "handled exceptions" junit

I have a method with a handled exception:
public boolean exampleMethod(){
try{
Integer temp=null;
temp.equals(null);
return
}catch(Exception e){
e.printStackTrace();
}
}
I want to test it
public void test_exampleMethod(){}
I have tried
#Rule
public ExpectedException expectedException=ExpectedException.none();
public void test_exampleMethod(){
expectedException.expect(JsonParseException.class);
exampleMethod();
}
but that doesnt work because the exception is handled inside.
I also tried
#Test(expected=JsonParseException.class)
but same issue...the exception is handled
I know that I can just do
assertTrue(if(exampleMethod()))
but it will still print the stack trace to the log. I would prefer clean logs...Any suggestions?
You cannot test what a method is doing internally. This is completely hidden (unless there are side effects, that are visible outside).
The test can check that for a specific input the method returns a expected output. But you can not check, how this is done. So you have no way to detect if there was a exception that you have handled.
So: either don't handle the exception (let the test catch the exception), or return a special value that tells you about the exception.
Anyway, I hope your real exception handling is more sensible than in your example.
If the method does not throw an exception you cannot expect to get one!
Below an example how write a Junit Test for a method that throws an Exception:
class Parser {
public void parseValue(String number) {
return Integer.parseInt(number);
}
}
Normal test case
public void testParseValueOK() {
Parser parser = new Parser();
assertTrue(23, parser.parseValue("23"));
}
Test case for exception
public void testParseValueException() {
Parser parser = new Parser();
try {
int value = parser.parseValue("notANumber");
fail("Expected a NumberFormatException");
} catch (NumberFormatException ex) {
// as expected got exception
}
}

How to re-throw exception in AspectJ around advise

I have some methods which throws some exception, and I want to use AspectJ around advise to calculate the execution time and if some exception is thrown and to log into error log and continue the flow by re-throwing the exception.
I tried to achieve this by following but eclipse says "Unhandled Exception type".
Code-against whom AspectJ is to used :-
public interface Iface {
public void reload() throws TException;
public TUser getUserFromUserId(int userId, String serverId) throws ResumeNotFoundException, TException;
public TUser getUserFromUsername(String username, String serverId) throws ResumeNotFoundException, TException;
public TResume getPartialActiveProfileFromUserId(int userId, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException;
public TResume getPartialActiveProfileFromUsername(String username, int sectionsBitField, String serverId) throws ResumeNotFoundException, UserNotFoundException, TException;
}
Code AspectJ :-
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
Object ret;
Throwable ex = null;
StopWatch watch = new Slf4JStopWatch();
try {
ret = proceed();
} catch (UserNotFoundException e) {
ex = e;
throw e;
} catch (ResumeNotFoundException e) {
ex = e;
throw e;
} catch (Throwable e) {
ex = e;
throw new RuntimeException(e);
} finally {
watch.stop(thisJoinPoint.toShortString());
if (ex != null) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
numEx++;
}
}
return ret;
}
}
Please help why this AspectJ is not working.
you can avoid catching the exceptions and just use a try/finally block without the catch.
And if you really need to log the exception you can use an after throwing advice, like this:
public aspect AspectServerLog {
public static final Logger ERR_LOG = LoggerFactory.getLogger("error");
Object around() : call (* com.abc.Iface.* (..)) {
StopWatch watch = new Slf4JStopWatch();
try {
return proceed();
} finally {
watch.stop(thisJoinPoint.toShortString());
}
}
after() throwing (Exception ex) : call (* com.abc.Iface.* (..)) {
StringBuilder mesg = new StringBuilder("Exception in ");
mesg.append(thisJoinPoint.toShortString()).append('(');
for (Object o : thisJoinPoint.getArgs()) {
mesg.append(o).append(',');
}
mesg.append(')');
ERR_LOG.error(mesg.toString(), ex);
}
}
I'm afraid you cannot write advice to throw exceptions that aren't declared to be thrown at the matched join point. Per: http://www.eclipse.org/aspectj/doc/released/progguide/semantics-advice.html :
"An advice declaration must include a throws clause listing the checked exceptions the body may throw. This list of checked exceptions must be compatible with each target join point of the advice, or an error is signalled by the compiler."
There has been discussion on the aspectj mailing list about improving this situation - see threads like this: http://dev.eclipse.org/mhonarc/lists/aspectj-dev/msg01412.html
but basically what you will need to do is different advice for each variant of exception declaration. For example:
Object around() throws ResumeServiceException, ResumeNotFoundException, TException:
call (* Iface.* (..) throws ResumeServiceException, ResumeNotFoundException, TException) {
that will advise everywhere that has those 3 exceptions.
There is an "ugly" workaround - I found them in Spring4 AbstractTransactionAspect
Object around(...): ... {
try {
return proceed(...);
}
catch (RuntimeException ex) {
throw ex;
}
catch (Error err) {
throw err;
}
catch (Throwable thr) {
Rethrower.rethrow(thr);
throw new IllegalStateException("Should never get here", thr);
}
}
/**
* Ugly but safe workaround: We need to be able to propagate checked exceptions,
* despite AspectJ around advice supporting specifically declared exceptions only.
*/
private static class Rethrower {
public static void rethrow(final Throwable exception) {
class CheckedExceptionRethrower<T extends Throwable> {
#SuppressWarnings("unchecked")
private void rethrow(Throwable exception) throws T {
throw (T) exception;
}
}
new CheckedExceptionRethrower<RuntimeException>().rethrow(exception);
}
}

Junit exception handling

I want to know that whether this test case should pass or fail
beacause
expected = IndexOutOfBoundsException.class
and actually it is throwing Arithmatic exception. can anyone explain?
#Test(expected = IndexOutOfBoundsException.class)
public void testDivideNumbers()throws ArithmeticException{
try{
double a = 10/0;
fail("Failed: Should get an Arithmatic Exception");
}
catch (ArithmeticException e) {
}
}
To test that the correct exception is thrown you should not have the test method throw the exception but just have the test itself result in the thrown exception.
So if ArithmeticException is expected then the test should be:
#Test(expected = ArithmeticException.class)
public void testDivideNumbers() {
double a = 10/0;
}
It should fail because it doesn't throw any exception; the ArithmeticException is caught and swallowed by the catch block.
This test is expecting to get an IndexOutOfBoundsException thrown. Because that does not happen in the test, the test fails. You can "fix" the test like this:
#Test(expected = IndexOutOfBoundsException.class)
public void testDivideNumbers() {
try {
double a = 10/0;
Assert.fail("Failed: Should get an Arithmetic Exception");
}
catch (ArithmeticException e) {
// Assert that this exception is thrown as expected
Assert.assertEquals("/ by zero", e.getMessage());
}
throw new IndexOutOfBoundsException();
}
You should not leave the catch block empty. You should always put some assert in it proving that the fail() didn't happen and the catch did happen and, importantly, happened for the reason you expected.