@Test
 public void retryOnOriginalEvent() throws Exception {
   when(mockUntilSuccessfulConfiguration.getFailureExpressionFilter())
       .thenReturn(mockAlwaysTrueFailureExpressionFilter);
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   when(mockRoute.process(any(MuleEvent.class)))
       .then(
           new Answer<MuleEvent>() {
             @Override
             public MuleEvent answer(InvocationOnMock invocation) throws Throwable {
               MuleEvent argEvent = (MuleEvent) invocation.getArguments()[0];
               assertThat(argEvent.getMessageAsString(), is(TEST_DATA));
               argEvent.getMessage().setPayload(PROCESSED_DATA);
               return argEvent;
             }
           });
   try {
     processingStrategy.route(event);
     fail("processing should throw exception");
   } catch (MessagingException e) {
     assertThat(e, instanceOf(RoutingException.class));
     verify(mockRoute, times(DEFAULT_RETRIES + 1)).process(event);
     verify(mockAlwaysTrueFailureExpressionFilter, times(DEFAULT_RETRIES + 1))
         .accept(any(MuleMessage.class));
   }
 }
 @Test
 public void successfulExecution() throws Exception {
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   when(mockRoute.process(event)).thenReturn(event);
   assertThat(processingStrategy.route(event), is(event));
   verify(mockRoute).process(event);
 }
 private SynchronousUntilSuccessfulProcessingStrategy createProcessingStrategy()
     throws InitialisationException {
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy =
       new SynchronousUntilSuccessfulProcessingStrategy();
   processingStrategy.setUntilSuccessfulConfiguration(mockUntilSuccessfulConfiguration);
   processingStrategy.initialise();
   return processingStrategy;
 }
 @Test
 public void alwaysFail() throws MuleException {
   when(mockRoute.process(any(MuleEvent.class)))
       .thenThrow(new RuntimeException("expected failure"));
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   try {
     processingStrategy.route(event);
     fail("processing should throw exception");
   } catch (MessagingException e) {
     assertThat(e, instanceOf(RoutingException.class));
     verify(mockRoute, times(DEFAULT_RETRIES + 1)).process(event);
   }
 }
 @Test
 public void alwaysFailUsingFailureExpression() throws MuleException {
   when(mockUntilSuccessfulConfiguration.getFailureExpressionFilter())
       .thenReturn(mockAlwaysTrueFailureExpressionFilter);
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   try {
     processingStrategy.route(event);
     fail("processing should throw exception");
   } catch (MessagingException e) {
     assertThat(e, instanceOf(RoutingException.class));
     verify(mockRoute, times(DEFAULT_RETRIES + 1)).process(event);
     verify(mockAlwaysTrueFailureExpressionFilter, times(DEFAULT_RETRIES + 1))
         .accept(any(MuleMessage.class));
   }
 }
 @Test
 public void successfulExecutionWithAckExpression() throws Exception {
   String ackExpression = "some-expression";
   String expressionEvalutaionResult = "new payload";
   event.setMessage(spy(event.getMessage()));
   when(mockUntilSuccessfulConfiguration.getAckExpression()).thenReturn(ackExpression);
   when(mockUntilSuccessfulConfiguration
           .getMuleContext()
           .getExpressionManager()
           .evaluate(ackExpression, event))
       .thenReturn(expressionEvalutaionResult);
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   when(mockRoute.process(event)).thenReturn(event);
   assertThat(processingStrategy.route(event), is(event));
   verify(mockRoute).process(event);
   verify(mockUntilSuccessfulConfiguration.getMuleContext().getExpressionManager())
       .evaluate(ackExpression, event);
   verify(event.getMessage()).setPayload(expressionEvalutaionResult);
 }
 @Test
 public void successfulWithNullEventResponseFromRoute() throws Exception {
   when(mockRoute.process(event)).thenReturn(VoidMuleEvent.getInstance());
   SynchronousUntilSuccessfulProcessingStrategy processingStrategy = createProcessingStrategy();
   assertThat((VoidMuleEvent) processingStrategy.route(event), is(VoidMuleEvent.getInstance()));
 }