@Test
 public void shouldRetryIfRetryableTaskThrowsUncheckedException() {
   int maxRetries = 5;
   String message = taskSerializer.serialize(new MockRetryableDeferredTask(maxRetries));
   queueProvider.send(message);
   for (int i = 0; i < maxRetries; i++) {
     deferredTaskService.processQueue();
   }
 }
  @Test
  public void shouldWrapExceptionIfTaskThrowsUncheckedException() {
    thrown.expect(ThundrDeferredException.class);
    thrown.expectMessage("Running deferred task failed permanently. Reason: Expected baby!");

    String message = taskSerializer.serialize(new MockExceptionThrowingDeferredTask());
    queueProvider.send(message);
    deferredTaskService.processQueue();
  }
  @Test
  public void shouldSerializeTaskIntoMessage() {
    deferredTaskService.defer(new MockDeferredTask());

    ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
    verify(queueProvider, times(1)).send(captor.capture());
    String message = taskSerializer.serialize(new MockDeferredTask());
    assertThat(captor.getValue(), equalTo(message));
  }
  @Test
  public void shouldThrowExceptionIfTaskClassNotFound() {
    thrown.expect(ThundrDeferredException.class);
    thrown.expectMessage("Unable to deserialize task from queue. Class foo.bar.MIA not found.");

    String message =
        "{\"taskClassName\":\"foo.bar.MIA\",\"taskData\":\"{\\\"field\\\":\\\"foo\\\"}\"}";
    queueProvider.send(message);
    deferredTaskService.processQueue();
  }
  @Test
  public void shouldFailPermanentlyIfRetryableTaskExceedsMaxRetries() {
    thrown.expect(ThundrDeferredException.class);
    thrown.expectMessage("Max retries[2] exceeded. Giving up!");

    int maxRetries = 2;
    String message = taskSerializer.serialize(new MockRetryableDeferredTask(maxRetries));
    queueProvider.send(message);
    for (int i = 0; i < maxRetries; i++) {
      deferredTaskService.processQueue();
    }
  }