Spring MVC 测试 3.2.2 由于某些奇怪的原因失败 "flash().attributeExists"断言

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

我正在测试以下Spring MVC Controller 方法:

@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 系统地使测试失败!

您可以亲眼看到,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。

最佳答案

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

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

FlashAttributeResultMatcher 上调用 attributeExists(),但它仅检查是否存在 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);
                }
            }
        };
    }

因此断言失败。

关于Spring MVC 测试 3.2.2 由于某些奇怪的原因失败 "flash().attributeExists"断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19051954/

相关文章:

Spring、JPA 事务仅在 JUnit 测试中有效,但在应用程序中无效

java - 在 spring data mongodb 存储库的 @Query 注释中使用 $or 运算符

java - 您如何使用可以动态更改的spring指定数据源

android - 我如何测试没有为非模拟对象调用方法?

java - Mockito:当方法的返回类型为void时如何获取传递给方法的参数

android - 如何使用 Mockito 和 Robolectric 模拟 Context?

java - 通过 Maven 在 Spring Boot 中配置 Activity 配置文件

spring - 获取 RedisConnectionFailureException

java - 如何在 spring security/thymeleaf 中自动生成 csrf token 而不使用 @EnableWebMvcSecurity

java - Spring Boot 程序找不到主类