8

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.

helvete
  • 2,455
  • 13
  • 33
  • 37
Sawyer
  • 423
  • 1
  • 7
  • 23
  • I have tried to do it but unable to get what I am missing. – Sawyer Aug 24 '17 at 13:34
  • @Sawyer The code snippet is incomplete, but I suggest to look again at your stub. – bric3 Aug 24 '17 at 14:36
  • I am not able to achieve the coverage and testing of Strings in Catch block. How do I do that. – Sawyer Aug 24 '17 at 14:38
  • 2
    Simple question: Does `SimpleClass.firec2TEvents` have a `throws Exception` in it's declaration? If not, then it may not throw `Exception`, since Exception is a checked Exception. If you want to test that catch block, you should make it throw a `RuntimeException` instead - or any declared checked Exception. This is what the failure is telling you: You are trying to throw a checked Exception, but the method in question does not declare throwing this checked Exception, so you are not allowed to throw that checked Exception. – Florian Schaetz Aug 24 '17 at 18:50
  • I appreciate the timely comeback ;-) – GhostCat Aug 28 '17 at 11:16

2 Answers2

8

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!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • How do I verify the contents of catch, can you please give me a hint? – Sawyer Aug 28 '17 at 07:56
  • 1
    It depends. If `Logger.log()` is a **static** call ... you *could* use PowerMock(ito) or JMockit to *verify* that a log call took place. I personally dislike mocking static calls, alternatively, you can: put an *instance* of some logging interface as member into that production class. And then: you can use *dependency injection* to provide a **mocked** logger object. Which again you can then *verify* calls on. Ok ... that were another 5 minutes ;-) – GhostCat Aug 28 '17 at 08:02
  • +1 to your information on the above and upvote for the answer for giving some knowledge with what happens with a mock and what is assumed. I acheived coverage though with the by InjectMocks on the Simple class and calling the runMethod() with uninitialized objects of this method parameters. You can edit the answer though, as you said to verfiy. – Sawyer Aug 28 '17 at 11:06
  • You are welcome, but I have to admit: I am not getting what you are trying to tell me. Anyway, I updated my answer ... – GhostCat Aug 28 '17 at 11:19
1

Manipulate the environment so that doesSomething() throws the Exception you want. Since we do not know what doesSomething() really does, one cannot say more.

Laurel
  • 5,965
  • 14
  • 31
  • 57
Heri
  • 4,368
  • 1
  • 31
  • 51
  • I see what you are trying to get at basically mockito does not allow any exception to be thrown other than those declared in the method signature. So, for this question to be answered we need signature of doesSomething() – Raghvendra Singh Mar 30 '21 at 12:55