Thursday, February 26, 2015

PowerMockito: java.lang.RuntimeException: PowerMock internal error

java.lang.RuntimeException: PowerMock internal error
    at org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing$InvokeStubMethod.invoke(DelegatingToConstructorsOngoingStubbing.java:133)
    at org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing.thenThrow(DelegatingToConstructorsOngoingStubbing.java:71)


I was working on some tests for a project that required the use of PowerMock and Mockito when in one of my tests I started getting the above error.

The test code looks something like this:
@Test 
public void testThrowIOException() throws Exception
{

    File file = mock(File.class);
    when(file.getAbsolutePath()).thenReturn("name.gz");
    IOException exception = new IOException("test message");
       PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenThrow(exception);
       
    try
    {

        Service service = new Service();
        service.method(file);
        fail("expected exception");
    }
    catch(Exception e)
    {
        assertTrue(e.getMessage().contains("test message"));
    }

}

After banging my head on the wall and after several hundred google searches which resulted in nothing I decided to just start tweaking things. The first thing I tried was to change the line
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenThrow(exception);
to
PowerMockito.whenNew(FileInputStream.class).withArguments(file).thenThrow(exception);
I did that since the code I'm testing does actually take an argument, I originally thought that since for the tests sake it didn't matter what the argument was I would use the AnyArguments method, but for some reason changing it to the method that takes arguments fixed my problem and let my tests complete successfully.

Unfortunately I'm not familiar enough with the underlying code to know or easily figure out why the first version caused problems but I think it's obvious that something about how the mock was created without the argument caused the exception and creating the mock with the argument addressed that issue.