Sawyer Sawyer - 2 months ago 29
Java Question

checked exception is invalid for this method

I have the below class
There is an answer to this in StackOverflow but it deals with List throw checked Exceptions from mocks with Mockito. I like to look into this condition. Not getting where I am missing.

public SimpleClass{
private SimpleClass(){}
public void runMethod(request,String,Map,Object,Object){
try{
doesSomething()....
}
}
catch(Exception e){
String message= ""+request.getAttribute(X)+"Some message"
Logger.Log(param1+param2+message);
}

}


My Test method looks like below. I trying to run the coverage with the JUnit but the Catch Block is not covered, so Wrote the below test method. It throws the below exception. Not able to get where I am missing.

public class SimpleClassTest{
@Test
public void testCatchBlock(){
SimpleClass instanceObj =PowerMockito.mock(SimpleClass.class);
Mockito.doThrow(new Exception()).when(instanceObj).runMethod(request, anyString(), anyMap(), anyObject(), anyObject());
}
}


Exception Thrown

org.mockito.exceptions.base.MockitoException:
Checked exception is invalid for this method!
Invalid: java.lang.Exception


Edit

I am able to run the method by giving NullPointerException. When I try for code coverage with Junit, the catch block is completely shown as red, and the catch phrase is shown yellow. How do I achieve 100% coverage and how to test the String message in the catch block.

Answer Source

You are getting unit testing with mocking wrong. Here:

SimpleClass instanceObj =PowerMockito.mock(SimpleClass.class);

There is no point in mocking the class that is under test!

When you mock that class, you get a stub that has "nothing to do" with your real implementation. A "working setup" would look more like:

public void methodUnderTest(X x, ...) {
   try { 
     x.foo(); 
   } catch (Exception e) {
    ...
}

and

 X mockedX = mock(X.class);
 when(x.foo()).thenThrow(new WhateverException());

 underTest.methodUnderTest(mockedX); ...

and then you could try to verify for example that the logger saw that expected logging call. In other words: you either use a mock to allow your code under test to do its job (with you being in control!) or to verify that some expected call took place on a mock object.

But as said: it doesn't make any sense to mock that class that you want to test. Because a mocked object doesn't know anything about the "real" implementation!