Pergunta

I am testing the following Spring MVC controller method:

@RequestMapping(value = "/passwordReset", method = RequestMethod.POST, produces = "text/html")
    public String resetPassword(@Validated({ ValidationGroups.PasswordReset.class }) @ModelAttribute PasswordInfo passwordInfo,   
            BindingResult bindingResult, Model model, RedirectAttributes redirectAttributes, Locale locale) {
        if (bindingResult.hasErrors()) {
            model.addAttribute("passwordInfo", passwordInfo);
            return "passwordReset";
        }
        redirectAttributes.addFlashAttribute("message", messageSource.getMessage("controller.preference.password_reset_ok", null, locale));
        Member member = preferenceService.findMemberByToken(passwordInfo.getToken());
        preferenceService.modifyPassword(member, passwordInfo.getNewPassword());
        signinService.signin(member);
        return "redirect:/preference/email";
    }

Here is my test method:

@Test
    public void resetPasswordShouldHaveNormalInteractions() throws Exception {
        Member member = new Member();
        when(preferenceService.findMemberByToken(eq("valid-token"))).thenReturn(member);
        mockMvc.perform(post("/preference/passwordReset")//
                .param("newPassword", "valid-password")//
                .param("token", "valid-token"))//
                .andDo(print())
                .andExpect(redirectedUrl("/preference/email"))//
                .andExpect(flash().attributeExists("message"))//FAILS HERE
                .andExpect(flash().attributeCount(1));
        verify(preferenceService).modifyPassword(eq(member), eq("valid-password"));
        verify(signinService).signin(eq(member));
    }

Even though the "message" flash attribute is added to the redirect attribute map, Spring MVC test does not seem to notice it and the line above FAILS HERE sytematically fails the test!

You can see for yourself that the message flash attribute is indeed in the FlashMap (see doPrint()) below:

MockHttpServletRequest:
         HTTP Method = POST
         Request URI = /preference/passwordReset
          Parameters = {newPassword=[valid-password], token=[valid-token]}
             Headers = {}

             Handler:
                Type = com.bignibou.controller.preference.PreferenceController
              Method = public java.lang.String com.bignibou.controller.preference.PreferenceController.resetPassword(com.bignibou.controller.preference.PasswordInfo,org.springframework.validation.BindingResult,org.springframework.ui.Model,org.springframework.web.servlet.mvc.support.RedirectAttributes,java.util.Locale)

               Async:
   Was async started = false
        Async result = null

  Resolved Exception:
                Type = null

        ModelAndView:
           View name = redirect:/preference/email
                View = null
               Model = null

            FlashMap:
           Attribute = message
               value = null

MockHttpServletResponse:
              Status = 302
       Error message = null
             Headers = {Location=[/preference/email]}
        Content type = null
                Body = 
       Forwarded URL = null
      Redirected URL = /preference/email
             Cookies = []

Can anyone please help? FYI I use Spring 3.2.2.

Foi útil?

Solução

As seen in the output of doPrint() FlashMap contains an attribute "message" with the value null.

.andExpect(flash().attributeExists("message"))

calls attributeExists() on an FlashAttributeResultMatcher but it only checks if there is an not null attribute:

/**
     * Assert the existence of the given flash attributes.
     */
    public <T> ResultMatcher attributeExists(final String... names) {
        return new ResultMatcher() {
            public void match(MvcResult result) throws Exception {
                for (String name : names) {
                    assertTrue("Flash attribute [" + name + "] does not exist", result.getFlashMap().get(name) != null);
                }
            }
        };
    }

Therefore the assertion fails.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top