Search code examples
javapowermockito

powermockito - testing exception handling


Testing a snip:

void somefunction() {
  try {
    aMock.doSomething();
    bMock.another();
  } finally {
    cMock.cleanup();
  }
}

Test:

@Test(expected = Exception.class)
void sometest() {
  ... setup various mocks ...

  PowerMockito.doThrow(new Exception("abc")).when(aMock).doSomething();

  outerMock.somefunction();

  // ** THIS SHOULD FAIL
  verify(bMock).another();

  // ** THIS SHOULD FAIL TOO
  verify(cMock, never()).cleanup()
}

When I run this it passes. Why? Does the throw Exception (and handling in @Test) trump the verify statements?

If so - is there some way to test that the finally clause was executed?


Solution

  • Because the exception is thrown (for real), everything under your function code is dead code.

    outerMock.somefunction();  // throw so, this is the end
    
    // ------- dead code blow:
    // ** THIS SHOULD FAIL
    verify(bMock).another();
    
    // ** THIS SHOULD FAIL TOO
    verify(cMock, never()).cleanup()
    

    So to test the finally block you have to use a normal execution (when no exception occurs). Another solution would be to use a try/catch in the test:

    try {
        outerMock.somefunction();
        fail("was expecting an exception..");
    } catch(Exception exception) {
        // ignore
    }
    
    verify(bMock).another();
    verify(cMock, never()).cleanup()
    

    To answer to the question in comments:

    assuming the code is now:

    void somefunction() {
        try {
            aMock.doSomething();
            bMock.another();
        } catch(Exception ex) {
            cMock.handleException(ex);
        }
    }
    

    the test could be:

    Exception testEx = new Exception("testing")
    Mockito.when(aMock.doSomething()).thenThrow(testEx);
    instance.somefunction();
    Mockito.verify(cMock).handleException(testEx);