SafetyNet { public void executeSafelyOnNewThread(final Runnable runnable) { if (forceMainThreadReport) { executeSafely(runnable); } else { new Thread(new Runnable() { @Override public void run() { executeSafely(runnable); } }).start(); } } SafetyNet(CrashReporterApiClient crashReporterApiClient);   SafetyNet(CrashReporterApiClient crashReporterApiClient, boolean forceMainThreadReport); void executeSafelyOnNewThread(final Runnable runnable); void executeSafely(Runnable runnable);  }
@Test public void sendsTheExceptionCatchToTheCrashReporterApiClientOnANewThread() { NullPointerException nullPointerException = new NullPointerException(); BrokenRunnable brokenRunnable = new BrokenRunnable(nullPointerException); safetyNet.executeSafelyOnNewThread(brokenRunnable); verify(apiClient).reportError(nullPointerException); }
@Test public void doesNotSendAnyExceptionIfThereIsNoCrashOnANewThread() { safetyNet.executeSafelyOnNewThread(new Runnable() { @Override public void run() { } }); verify(apiClient, never()).reportError(any(Throwable.class)); }