I am testing the following Spring MVC controller method:
@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";
}
Here is my test method:
@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));
}
Even though the "message" flash attribute is added to the redirect attribute map, Spring MVC test does not seem to notice it and the line above FAILS HERE
sytematically fails the test!
You can see for yourself that the message
flash attribute is indeed in the FlashMap (see doPrint()
) below:
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 = []
Can anyone please help? FYI I use Spring 3.2.2.
As seen in the output of doPrint() FlashMap contains an attribute "message" with the value null.
.andExpect(flash().attributeExists("message"))
calls attributeExists()
on an FlashAttributeResultMatcher
but it only checks if there is an not null attribute:
/**
* 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);
}
}
};
}
Therefore the assertion fails.