简体   繁体   中英

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 DeadEvent s, 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM