Announcement Announcement Module
Collapse
No announcement yet.
Can't map request attribs to POJO in unit test in SpringMVC Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Can't map request attribs to POJO in unit test in SpringMVC

    Hi there,

    I have some unit tests for a form controller. The controller behaves correctly when called by a real request. But I'm not able to simulate request parameters being mapped to a POJO. Here's my test case:

    Code:
        public void testSave() throws Exception {
            FSUserFormController wFormController = (FSUserFormController)ctx.getBean(FSMVCDefs.USER_FORM_CONTROLLER);
            FSAdminService wAdminService = (FSAdminService)ctx.getBean(FSSharedDefs.ADMIN_SERVICE);
            MockHttpServletRequest wRequest = new MockHttpServletRequest(FSTestDefs.CMOCK_REQUEST_TYPE, FSTestDefs.CEDIT_USERS_URL);
    
            FSUser wUser = getNewUser();
    
            wAdminService.saveUser(wUser);
            try {
                wRequest.addParameter(FSMVCDefs.ACT_SAVE, "");
                wRequest.addParameter(FSMVCDefs.ATT_ID, wUser.getId().toString());
                wRequest.addParameter("user.userName", wUser.getUserName() + " updated");
                wRequest.addParameter("user.password", wUser.getUserName() + " updated");
                wRequest.addParameter("user.firstName", wUser.getFirstName() + " updated");
                wRequest.addParameter("user.lastName", wUser.getLastName() + " updated");
                
                ModelAndView wModelAndView = wFormController.handleRequest(wRequest, new MockHttpServletResponse());
    
                Errors wErrors =
                    (Errors) wModelAndView.getModel().get(BindException.ERROR_KEY_PREFIX + FSMVCDefs.USER_VIEW_OBJECT);
                assertTrue(wErrors.getErrorCount() == 0); 
                assertNotNull(wRequest.getSession().getAttribute(FSMVCDefs.ATT_MESSAGES));
                assertTrue(wModelAndView.getModel().containsKey(FSMVCDefs.USER_VIEW_OBJECT));
            } finally {
                wAdminService.deleteUser(wUser.getId());
            }
        }
    I see the save and id attributes correctly in the controller, but the user attributes don't get mapped to my command object. As I said, it works correctly when called by the real thing. Here's how it's declared in my Velocity form:

    Code:
    #springBind("user.id")
    <input type="hidden" name="id" value="$status.value"/> 
    
    <div class="messages">
    	#foreach&#40;$message in $messages&#41;
    		$!message
    		<br>
    	#end
    </div>
    
    <p>
    Username&#58;<br>
    #springFormInput&#40;"user.userName" ""&#41;
    </p>
    
    <p>
    Password&#58;<br>
    #springFormInput&#40;"user.password" ""&#41;
    </p>
    
    <p>
    First Name&#58;<br>
    #springFormInput&#40;"user.firstName" ""&#41;
    </p>
    
    <p>
    Last Name&#58;<br>
    #springFormInput&#40;"user.lastName" ""&#41;
    </p>
    I have traced the source code in Spring and tried prefixing my attributes with an underscore, but it does not work either.

    I know that I do not test for the updated values being effectively posted. I didn't want my test case to fail. I'll add the checks later.

    Here's the relevant code from the controller:

    Code:
        protected void initBinder&#40;HttpServletRequest request, ServletRequestDataBinder binder&#41; &#123;
            FSUtils.removeWarning&#40;request&#41;;
            //NumberFormat nf = NumberFormat.getNumberInstance&#40;&#41;;
            binder.registerCustomEditor&#40;Long.class, null,
                    new CustomNumberEditor&#40;Long.class, true&#41;&#41;;
        &#125;
        
        /**
         * 
         */
        public ModelAndView onSubmit&#40;HttpServletRequest request,
                HttpServletResponse response, Object command,
                BindException errors&#41;
        throws Exception &#123;
            // Note that the model Map as returned by errors.getModel&#40;&#41; contains both the command object
            // &#40;under the command name&#41; and the corresponding Errors instance - no need to manually add the
            // command to the model.
            // See onSubmit for the ModelAndView creation. 
    
            ModelAndView wModelAndView = super.onSubmit&#40;request, response, command, errors&#41;;
            List wMessages = new ArrayList&#40;&#41;;
            request.getSession&#40;&#41;.setAttribute&#40;FSMVCDefs.ATT_MESSAGES, wMessages&#41;;
            
            FSUser wUser = &#40;FSUser&#41;command;
    
            String wRedirectView = request.getParameter&#40;FSMVCDefs.ATT_REDIRECT_VIEW&#41;;
            if &#40;&#40;wRedirectView != null&#41; && !wRedirectView.equals&#40;""&#41;&#41; &#123;
                wModelAndView.setView&#40;new RedirectView&#40;wRedirectView&#41;&#41;;
            &#125;
    
            if &#40;request.getParameter&#40;FSMVCDefs.ACT_DELETE&#41; != null&#41; &#123;
                adminService.deleteUser&#40;wUser.getId&#40;&#41;&#41;;
                String wMessage = getMessageSourceAccessor&#40;&#41;.getMessage&#40;"user.deleted", 
                        new Object&#91;&#93; &#123;wUser.getFirstName&#40;&#41; + ' ' + wUser.getLastName&#40;&#41;&#125;&#41;; 
                wMessages.add&#40;wMessage&#41;;
            &#125; else if &#40;request.getParameter&#40;FSMVCDefs.ACT_SAVE&#41; != null&#41; &#123;
                adminService.saveUser&#40;wUser&#41;;
                String wMessage = getMessageSourceAccessor&#40;&#41;.getMessage&#40;"user.saved", 
                        new Object&#91;&#93; &#123;wUser.getFirstName&#40;&#41; + ' ' + wUser.getLastName&#40;&#41;&#125;&#41;; 
                wMessages.add&#40;wMessage&#41;;
            &#125; else if &#40;request.getParameter&#40;FSMVCDefs.ACT_GOBACK&#41; != null&#41; &#123;
                String wMessage = getMessageSourceAccessor&#40;&#41;.getMessage&#40;"user.cancel", 
                        new Object&#91;&#93; &#123;wUser.getFirstName&#40;&#41; + ' ' + wUser.getLastName&#40;&#41;&#125;&#41;; 
                wMessages.add&#40;wMessage&#41;;
            &#125;
            
            return wModelAndView;
        &#125;
        
        protected Object formBackingObject&#40;HttpServletRequest request&#41; throws Exception &#123;
            String wUserId = request.getParameter&#40;FSMVCDefs.ATT_ID&#41;;
            FSUser wResult = null;
            
            if &#40;&#40;wUserId != null&#41; && !wUserId.equals&#40;""&#41;&#41; &#123;
                wResult = adminService.loadUser&#40;new Long&#40;wUserId&#41;&#41;;
                // This can be an old page and the user may not be in the database anymore.
            &#125; 
                
            if &#40;wResult == null&#41; &#123;
                // It's a new user. Retrieve command class defined in servlet xml config.
                
                wResult = &#40;FSUser&#41;super.formBackingObject&#40;request&#41;;
                
                // Set default values.
                
                wResult.setUserName&#40;FSServerDefs.NEW_USER_USERNAME&#41;;
                wResult.setPassword&#40;FSServerDefs.NEW_USER_PASSWORD&#41;;
                wResult.setFirstName&#40;FSServerDefs.NEW_USER_FIRSTNAME&#41;;
                wResult.setLastName&#40;FSServerDefs.NEW_USER_LASTNAME&#41;;
                
                adminService.saveUser&#40;wResult&#41;;
            &#125;
            
            return wResult;
        &#125;
    Thanx a lot!

    Starman

  • #2
    haven't gone through all your code, but try:
    Code:
    wRequest.addParameter&#40;"userName", wUser.getUserName&#40;&#41; + " updated"&#41;;
    without the "user." in front of it

    - Assaf

    Comment

    Working...
    X