Uncaught exceptions fail JUnit tests, just as we would expect. An uncaught exception in our code will crash the application, so we’d rightfully want uncaught exceptions to fail our unit tests too!
We might also expect that an uncaught exception in an RxJava chain would fail our unit tests. These exceptions cause crashes when they go to the default error handler, so they should fail our tests too, right?
Unfortunately that is not the case.
Here’s a sample test we can run to show this behavior:
Under the hood, RxJava’s default error handler does this with uncaught exceptions:
This looks fine, but has subtly different behavior in a JUnit test vs. your application. To understand why, we need to know how JUnit fails our tests when they throw an exception. JUnit’s test runner actually wraps your code in a try-catch (source) that looks something like this:
RxJava’s error handler does not re-throw any exceptions it catches, bypassing JUnit’s try-catch and delivering the exception directly to the Thread.getUncaughtExceptionHandler()
. Thus JUnit has nothing to catch and isn’t aware that the test threw an exception.
The easiest way to ensure that uncaught exceptions fail your tests is to create a JUnit rule that installs a custom error handler. Here’s one that I’ve been using based on AutoDispose’s implementation.
You can then apply it to your tests like so:
You can read more about this issue and find a number of other solutions on RxJava’s GitHub here
The solution I provided above with a JUnit rule can be a bit of a pain because you need to manually apply it to your tests. As recommended by others in the issue thread, you could use a JVM agent to apply a similar solution across your entire project.