title: Issues integration testing a Spring MVC controller method that calls an async Spring service method
body: <p>I have the following Spring MVC controller method:</p>
  
  <pre><code>@RequestMapping(value = "/sendPasswordReset", method = RequestMethod.POST, produces = "text/html")
  public String sendPasswordResetInformation(@ModelAttribute @Validated({ ValidationGroups.PasswordReset.class }) PasswordResetInfo passwordResetInfo,
          BindingResult bindingResult, Model model, final RedirectAttributes redirectAttributes, Locale locale) throws InterruptedException, ExecutionException {
      if (preferenceService.isEmailAvailable(passwordResetInfo.getEmail())) {
          bindingResult.rejectValue("email", "controller.preference.email_not_in_system");
      }
      if (bindingResult.hasErrors()) {
          model.addAttribute("passwordResetInfo", passwordResetInfo);
          return "preference/sendPasswordReset";
      }
      redirectAttributes.addFlashAttribute("flashMessage", messageSource.getMessage("controller.preference.password_reset_info_sent", null, locale));
      Future&lt;Void&gt; future = preferenceService.sendPasswordResetInfo(passwordResetInfo.getEmail());//.get();//TODO is ".get()" ugly?
      future.get();//NPE HERE!!
      return "redirect:/preference/sendPasswordReset";
  }
  </code></pre>
  
  <p>Here is the implementation of <code>sendPasswordResetInfo</code>:</p>
  
  <pre><code>@Async
  @Override
  public Future&lt;Void&gt; sendPasswordResetInfo(String email) {
      Assert.hasText(email);
      Member member = memberRepository.findByEmail(email);
      try {
          mailerService.doMailPasswordResetInfo(member);
          return new AsyncResult&lt;Void&gt;(null);
      } catch (MessagingException | MailSendException e) {
          log.error("MessagingException | MailSendException", e);
          throw new MailerException("MessagingException | MailSendException");
      }
  }
  </code></pre>
  
  <p>Here is how I am trying to integration test the controller method:</p>
  
  <pre><code>@Test
  public void sendPasswordResetShouldHaveNormalInteractions() throws Exception {
      when(preferenceService.isEmailAvailable(anyString())).thenReturn(Boolean.FALSE);
      mockMvc.perform(post("/preference/sendPasswordReset")//
              .param("email", VALID_EMAIL))//
              .andExpect(redirectedUrl("/preference/sendPasswordReset"))//
              .andExpect(flash().attributeExists("flashMessage"))//
              .andExpect(flash().attributeCount(1));
      verify(preferenceService).sendPasswordResetInfo(eq(VALID_EMAIL));
      reset(preferenceService);
  }
  </code></pre>
  
  <p>I systematically get a NullPointerException (in tests) in the controller method because the future object is null here:</p>
  
  <pre><code>future.get()
  </code></pre>
  
  <p>However the controller method runs fine when I use the app (outside of tests).</p>
  
  <p>I have tried using a sync task executor as follows (to no avail):</p>
  
  <pre><code>@Profile(Profiles.TEST)
  @Configuration
  @EnableAsync
  public class FakeAsyncConfiguration implements AsyncConfigurer {
  
      @Override
      public Executor getAsyncExecutor() {
          SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
          return taskExecutor;
      }
  
      @Override
      public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
          return new SimpleAsyncUncaughtExceptionHandler();
      }
  }
  </code></pre>
  
  <p>My questions are:</p>
  
  <ul>
  <li>Why is the <code>Future</code> object always null during the integration tests and </li>
  <li>How can I ensure it is not null during my integration tests?</li>
  </ul>