user1768830
user1768830

Reputation:

Mockito 1.9.5 causing NullPointerException

I have a StandardUncaughtExceptionHandler which catches any exceptions that haven't been previously caught by other exceptions. Under the hood, I'm using a Guava EventBus for error handling. For each type of checked exception thrown in my app, I register an event handler with the bus to handle that specific exception type. If the bus posts an exception that it doesn't have a registered handler for, it wraps that exception in a DeadEvent object, and reposts the dead event back to the bus. This StandardUncaughtExceptionHandler is registered to listen for DeadEvents, guaranteeing me that I'll always have a way to check for uncaught exceptions.

Here's the main source:

public class StandardUncaughtExceptionHandler implements UncaughtExceptionHandler {
    private LoggingService loggingService;

    // Getter and setter for logginService.

    @Override @Subscribe
    public void handleUncaughtException(DeadEvent deadEvent) {
        // Log it.
        StringBuilder logBuilder = new StringBuilder();

        if(deadEvent.getEvent() instanceof Throwable) {
            Throwable throwable = (Throwable)deadEvent.getEvent();

            logBuilder.append("An uncaught exception occurred: ");
            logBuilder.append(throwable.getMessage());
            logBuilder.append(" - Stack trace: ");
            logBuilder.append(throwable.getStackTrace());
        }
        else
            logBuilder.append("Something weird happened.");

        loggingService.error(logBuilder.toString());
    }
}

And my test for it, checking to make sure that when we give it a Throwable that it constructs the correct log message.

@Test
public void handleUncaughtExceptionLogsThrowableIfPresent() {
    // GIVEN
    StandardUncaughtExceptionHandler fixture =
        new StandardUncaughtExceptionHandler();
    LoggingService mockLoggingService = Mockito.mock(LoggingService.class);
    DeadEvent mockDeadEvent = Mockito.mock(DeadEvent.class);

    Mockito.doThrow(new RuntimeException("Logging-Throwable"))
        .when(mockLoggingService)
        .error(Mockito.contains("An uncaught exception occurred:"));
    Mockito.doThrow(new RuntimeException("Logging-Something-Else"))
        .when(mockLoggingService)
        .error(Mockito.contains("Something weird happened."));
    Mockito.doReturn(new Throwable()).when(mockDeadEvent).getEvent();

    try {
        // WHEN
        fixture.handleUncaughtException(mockDeadEvent);

        Assert.fail();
    } catch(RuntimeException rte) {
        // THEN
        Assert.assertTrue(rte.getMessage().contains("Logging-Throwable"));
    }
}

When I run this test, I get the following error in my JUnit console:

java.lang.NullPointerException
    at com.myapp.StandardUncaughtExceptionHandlerTest.handleUncaughtExceptionLogsThrowableIfPresent(StandardUncaughtExceptionHandlerTest.java:63)
    ... rest of stack trace omitted for brevity, it's huge

Any ideas as to why Mockito is causing the NPEs? I've checked and rechecked and I believe I've set my mocks up correctly. Thanks in advance.

Upvotes: 1

Views: 500

Answers (1)

harpun
harpun

Reputation: 4110

Mockito is not the issue here.

I believe the NPE is reported in the following line of your test:

Assert.assertTrue(rte.getMessage().contains("Logging-Throwable"));

because rte.getMessage() returns null. Unfortunately due to the try-catch block in your unit test, the real origin of this error is hidden from you. Uncommenting try-catch in handleUncaughtExceptionLogsThrowableIfPresent() reveals the real issue: a NPE is thrown in the following line:

loggingService.error(logBuilder.toString());

because loggingService is never initialized in the StandardUncaughtExceptionHandler class. This field should be initialized in your test method with the mock or in any other valid way.

Upvotes: 3

Related Questions