2

我正在测试以下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));
    }

即使将“消息”闪存属性添加到重定向属性映射中,Spring MVC 测试似乎也没有注意到它,并且上面的行FAILS HERE系统性地未能通过测试!

您可以自己看到flash 属性确实在下面的 FlashMap 中message请参阅参考资料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。

4

1 回答 1

3

从 doPrint() 的输出中可以看出,FlashMap 包含一个值为 null 的属性“message”。

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

调用attributeExists()anFlashAttributeResultMatcher但它只检查是否存在非空属性:

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

因此断言失败。

于 2013-09-27T13:44:22.363 回答