### Question:
Task extends Thread { @Override public void run() { log.fine("Starting task " + taskId); try { performTask(); if (isInterrupted()) { writeStatus(TaskStatus.FAILOVER, "Task execution was interrupted"); } else if (canceled) { writeStatus(TaskStatus.CANCELED, null); } else { writeStatus(TaskStatus.FINISHED_OK, null); } } catch (InterruptedException | InterruptedIOException e) { writeStatus(TaskStatus.FAILOVER, "Task execution was interrupted"); } catch (IndexMissingException e) { writeStatus(TaskStatus.FINISHED_ERROR, "ERROR: Task finished due missing search index: " + e.getMessage()); } catch (RuntimeException e) { String msg = "Task execution interrupted due " + e.getClass().getName() + ": " + e.getMessage(); if (e instanceof NullPointerException) { msg = "Task execution interrupted due NullPointerException, see log file for stacktrace"; log.log(Level.SEVERE, "Task finished due NullPointerException", e); } writeStatus(TaskStatus.FAILOVER, "ERROR: " + msg); } catch (Exception e) { writeStatus(TaskStatus.FINISHED_ERROR, "ERROR: Task finished due exception: " + e.getMessage()); } finally { log.fine("Finished task " + taskId); } } Task(); void setExecutionContext(String taskId, TaskExecutionContext context); @Override void run(); boolean isCanceledOrInterrupted(); void setCanceled(boolean canceled);  }### Answer:
@Test public void run() throws InterruptedException { { Task tested = getTested(); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FINISHED_OK, null); } { Task tested = getTested(); tested.setCanceled(true); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.CANCELED, null); } { Task tested = getTested(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { throw new RuntimeException("my runtime exception message"); } }); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FAILOVER, "ERROR: Task execution interrupted due java.lang.RuntimeException: my runtime exception message"); } { Task tested = getTested(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { throw new IndexMissingException(new Index("my_index")); } }); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FINISHED_ERROR, "ERROR: Task finished due missing search index: [my_index] missing"); } { Task tested = getTested(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { throw new NullPointerException(); } }); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FAILOVER, "ERROR: Task execution interrupted due NullPointerException, see log file for stacktrace"); } { Task tested = getTested(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { throw new Exception("my exception message"); } }); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FINISHED_ERROR, "ERROR: Task finished due exception: my exception message"); } { Task tested = getTested(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { throw new InterruptedException(); } }); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FAILOVER, "Task execution was interrupted"); } { Task tested = getTested(new Answer<Boolean>() { @Override public Boolean answer(InvocationOnMock invocation) throws Throwable { throw new InterruptedIOException(); } }); tested.run(); Mockito.verify(tested.context).changeTaskStatus(TASK_ID, TaskStatus.FAILOVER, "Task execution was interrupted"); } }