【问题标题】:Spring MVC: How to bind to nested object properties in the @ModelAttributeSpring MVC:如何绑定到 @ModelAttribute 中的嵌套对象属性
【发布时间】:2016-05-11 10:17:25
【问题描述】:

我有一个基于以下代码部分的单元测试:

  @RequestMapping(value = "/changePass", method = RequestMethod.POST)
  public ModelAndView changePass(@ModelAttribute(TAPPLICATION) AppBean applicationBean, BindingResult result, ModelMap model, Principal principal, HttpServletRequest request) throws NSException, SQLException {
         // ...

         if (applicationBean != null
                    && applicationBean.getChangePassDto() != null
                    && StringUtils.isNotEmpty(applicationBean.getChangePassDto().getNewPassword())) {

                String newPassword = applicationBean.getChangePassDto().getNewPassword();
                // ...                   
            }
            // ...

AppBean 包含以下 getter 和 setter:

private ChangePassDto changePassDto;   

   public ChangePassDto getChangePassDto() {
        return changePassDto;
    }

    public void setChangePassDto(ChangePasswordDto changePassDto) {
        this.changePassDto = changePassDto;
    }

基本上,当我执行单元测试时,方法 applicationBean.getChangePassDto()nullapplicationBean 不为空。如何初始化applicationBean.getChangePassDto() 使其不返回null?我已经使用.param 方法初始化了其他非对象参数,这可以在我的单元测试中看到。

我也在使用 Powermock 作为单元测试框架。

请在下面找到我的单元测试的一部分:

    @Before
    public void setup() {

        request = new MockHttpServletRequest();
        request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
        response = new MockHttpServletResponse();
        session = new MockHttpSession();
        request.setSession(session);
        RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));

        //Added viewResolver to prevent circular view path error
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");

        this.mockMvc = MockMvcBuilders.standaloneSetup(appController).setViewResolvers(viewResolver).build();    
    }

    @Test
    public void changePass_ExpectC() throws Exception {

        PowerMockito.doNothing().when(passwordVal).validate(any(User.class), anyListOf(Params.class), any(Object.class),any(Errors.class));


        mockMvc.perform(post("/changePass").param("userLogName", "JOHN").param("userLogged", "userLogged").param("password", "password123").param("newPassword", "newPassword123").param("confirmNewPassword", "newPassword123"))
                 .andExpect(view().name(Constants.DENIED))
                .andExpect(status().isOk()
                 );
    }

知道如何初始化applicationBean.getchangePassDto() 使其不为空吗?

提前感谢您的帮助。

【问题讨论】:

    标签: java unit-testing spring-mvc powermock spring-test-mvc


    【解决方案1】:

    只需在您的AppBean 中创建ChangePassDto 的新实例:

    public class AppBean {
    
      private ChangePassDto changePassDto = new ChangePassDto();
    
      public ChangePassDto getChangePassDto() {
        return changePassDto;
      }
    
      public void setChangePassDto(ChangePasswordDto changePassDto) {
        this.changePassDto = changePassDto;
      }
    
      // ...
    }
    

    然后您需要使用嵌套 DTO 中属性的完整路径,如下所示:

    mockMvc.perform(post("/changePass")
        .param("changePassDto.userLogName", "JOHN")
        .param("changePassDto.userLogged", "userLogged")
        .param("changePassDto.password", "password123")
        .param("changePassDto.newPassword", "newPassword123")
        .param("changePassDto.confirmNewPassword", "newPassword123"))
    .andExpect(view().name(Constants.DENIED))
    .andExpect(status().isOk());
    

    【讨论】:

    • 嗨,我有一个问题,如果我在我的 appBean 中添加新的 ChangePassDto() 部分,Spring 不会管理 ChangePassDto 实例,因为它不是由 Spring 加载的?
    • 在这种情况下,Spring 不需要管理您的 DTO。相反,它只需要将请求参数绑定到 DTO 的属性。我会相应地更新我的答案。
    猜你喜欢
    • 2014-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 1970-01-01
    • 2011-04-17
    • 2020-11-21
    相关资源
    最近更新 更多