Starman
Sep 30th, 2004, 09:00 AM
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:
public void testSave() throws Exception {
FSUserFormController wFormController = (FSUserFormController)ctx.getBean(FSMVCDefs.USER_F ORM_CONTROLLER);
FSAdminService wAdminService = (FSAdminService)ctx.getBean(FSSharedDefs.ADMIN_SER VICE);
MockHttpServletRequest wRequest = new MockHttpServletRequest(FSTestDefs.CMOCK_REQUEST_TY PE, 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_K EY_PREFIX + FSMVCDefs.USER_VIEW_OBJECT);
assertTrue(wErrors.getErrorCount() == 0);
assertNotNull(wRequest.getSession().getAttribute(F SMVCDefs.ATT_MESSAGES));
assertTrue(wModelAndView.getModel().containsKey(FS MVCDefs.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:
#springBind("user.id")
<input type="hidden" name="id" value="$status.value"/>
<div class="messages">
#foreach($message in $messages)
$!message
<br>
#end
</div>
<p>
Username:<br>
#springFormInput("user.userName" "")
</p>
<p>
Password:<br>
#springFormInput("user.password" "")
</p>
<p>
First Name:<br>
#springFormInput("user.firstName" "")
</p>
<p>
Last Name:<br>
#springFormInput("user.lastName" "")
</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:
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
FSUtils.removeWarning(request);
//NumberFormat nf = NumberFormat.getNumberInstance();
binder.registerCustomEditor(Long.class, null,
new CustomNumberEditor(Long.class, true));
}
/**
*
*/
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command,
BindException errors)
throws Exception {
// Note that the model Map as returned by errors.getModel() contains both the command object
// (under the command name) 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(request, response, command, errors);
List wMessages = new ArrayList();
request.getSession().setAttribute(FSMVCDefs.ATT_ME SSAGES, wMessages);
FSUser wUser = (FSUser)command;
String wRedirectView = request.getParameter(FSMVCDefs.ATT_REDIRECT_VIEW);
if ((wRedirectView != null) && !wRedirectView.equals("")) {
wModelAndView.setView(new RedirectView(wRedirectView));
}
if (request.getParameter(FSMVCDefs.ACT_DELETE) != null) {
adminService.deleteUser(wUser.getId());
String wMessage = getMessageSourceAccessor().getMessage("user.deleted",
new Object[] {wUser.getFirstName() + ' ' + wUser.getLastName()});
wMessages.add(wMessage);
} else if (request.getParameter(FSMVCDefs.ACT_SAVE) != null) {
adminService.saveUser(wUser);
String wMessage = getMessageSourceAccessor().getMessage("user.saved",
new Object[] {wUser.getFirstName() + ' ' + wUser.getLastName()});
wMessages.add(wMessage);
} else if (request.getParameter(FSMVCDefs.ACT_GOBACK) != null) {
String wMessage = getMessageSourceAccessor().getMessage("user.cancel",
new Object[] {wUser.getFirstName() + ' ' + wUser.getLastName()});
wMessages.add(wMessage);
}
return wModelAndView;
}
protected Object formBackingObject(HttpServletRequest request) throws Exception {
String wUserId = request.getParameter(FSMVCDefs.ATT_ID);
FSUser wResult = null;
if ((wUserId != null) && !wUserId.equals("")) {
wResult = adminService.loadUser(new Long(wUserId));
// This can be an old page and the user may not be in the database anymore.
}
if (wResult == null) {
// It's a new user. Retrieve command class defined in servlet xml config.
wResult = (FSUser)super.formBackingObject(request);
// Set default values.
wResult.setUserName(FSServerDefs.NEW_USER_USERNAME );
wResult.setPassword(FSServerDefs.NEW_USER_PASSWORD );
wResult.setFirstName(FSServerDefs.NEW_USER_FIRSTNA ME);
wResult.setLastName(FSServerDefs.NEW_USER_LASTNAME );
adminService.saveUser(wResult);
}
return wResult;
}
Thanx a lot!
Starman
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:
public void testSave() throws Exception {
FSUserFormController wFormController = (FSUserFormController)ctx.getBean(FSMVCDefs.USER_F ORM_CONTROLLER);
FSAdminService wAdminService = (FSAdminService)ctx.getBean(FSSharedDefs.ADMIN_SER VICE);
MockHttpServletRequest wRequest = new MockHttpServletRequest(FSTestDefs.CMOCK_REQUEST_TY PE, 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_K EY_PREFIX + FSMVCDefs.USER_VIEW_OBJECT);
assertTrue(wErrors.getErrorCount() == 0);
assertNotNull(wRequest.getSession().getAttribute(F SMVCDefs.ATT_MESSAGES));
assertTrue(wModelAndView.getModel().containsKey(FS MVCDefs.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:
#springBind("user.id")
<input type="hidden" name="id" value="$status.value"/>
<div class="messages">
#foreach($message in $messages)
$!message
<br>
#end
</div>
<p>
Username:<br>
#springFormInput("user.userName" "")
</p>
<p>
Password:<br>
#springFormInput("user.password" "")
</p>
<p>
First Name:<br>
#springFormInput("user.firstName" "")
</p>
<p>
Last Name:<br>
#springFormInput("user.lastName" "")
</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:
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
FSUtils.removeWarning(request);
//NumberFormat nf = NumberFormat.getNumberInstance();
binder.registerCustomEditor(Long.class, null,
new CustomNumberEditor(Long.class, true));
}
/**
*
*/
public ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command,
BindException errors)
throws Exception {
// Note that the model Map as returned by errors.getModel() contains both the command object
// (under the command name) 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(request, response, command, errors);
List wMessages = new ArrayList();
request.getSession().setAttribute(FSMVCDefs.ATT_ME SSAGES, wMessages);
FSUser wUser = (FSUser)command;
String wRedirectView = request.getParameter(FSMVCDefs.ATT_REDIRECT_VIEW);
if ((wRedirectView != null) && !wRedirectView.equals("")) {
wModelAndView.setView(new RedirectView(wRedirectView));
}
if (request.getParameter(FSMVCDefs.ACT_DELETE) != null) {
adminService.deleteUser(wUser.getId());
String wMessage = getMessageSourceAccessor().getMessage("user.deleted",
new Object[] {wUser.getFirstName() + ' ' + wUser.getLastName()});
wMessages.add(wMessage);
} else if (request.getParameter(FSMVCDefs.ACT_SAVE) != null) {
adminService.saveUser(wUser);
String wMessage = getMessageSourceAccessor().getMessage("user.saved",
new Object[] {wUser.getFirstName() + ' ' + wUser.getLastName()});
wMessages.add(wMessage);
} else if (request.getParameter(FSMVCDefs.ACT_GOBACK) != null) {
String wMessage = getMessageSourceAccessor().getMessage("user.cancel",
new Object[] {wUser.getFirstName() + ' ' + wUser.getLastName()});
wMessages.add(wMessage);
}
return wModelAndView;
}
protected Object formBackingObject(HttpServletRequest request) throws Exception {
String wUserId = request.getParameter(FSMVCDefs.ATT_ID);
FSUser wResult = null;
if ((wUserId != null) && !wUserId.equals("")) {
wResult = adminService.loadUser(new Long(wUserId));
// This can be an old page and the user may not be in the database anymore.
}
if (wResult == null) {
// It's a new user. Retrieve command class defined in servlet xml config.
wResult = (FSUser)super.formBackingObject(request);
// Set default values.
wResult.setUserName(FSServerDefs.NEW_USER_USERNAME );
wResult.setPassword(FSServerDefs.NEW_USER_PASSWORD );
wResult.setFirstName(FSServerDefs.NEW_USER_FIRSTNA ME);
wResult.setLastName(FSServerDefs.NEW_USER_LASTNAME );
adminService.saveUser(wResult);
}
return wResult;
}
Thanx a lot!
Starman