Spring MVC测试3.2.2失败了“flash()。attributeExists”断言的一些奇怪的原因

时间:2013-09-27 13:25:48

标签: spring spring-mvc mockito spring-mvc-test

我正在测试以下 Spring MVC控制器方法

@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";
    }

这是我的测试方法

@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));
    }

即使将“message”flash属性添加到重定向属性映射中,Spring MVC测试似乎也没有注意到它,并且FAILS HERE上面的行在测试中未通过测试! < / p>

您可以自己查看 message Flash属性确实在FlashMap中(请参阅下面的doPrint()):

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 = []

任何人都可以帮忙吗?仅供参考我使用Spring 3.2.2。

1 个答案:

答案 0 :(得分:2)

如doPrint()的输出中所示,FlashMap包含一个值为null的属性“message”。

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

attributeExists()上调用FlashAttributeResultMatcher,但它只检查是否存在 not null 属性:

/**
     * 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);
                }
            }
        };
    }

因此断言失败。