My guess is that your messageSource is null. You are mocking your request, but not your messageSource, and where you are newing the login controller it's not being injected by Spring.
While running it would get injected by Spring automatically.
Edit to clarify:
First you need to be able to set it some how for testing. You can either add a setter or a constructor to get to it, such as:
@Controller
public class LogInController {
@Autowired
private MessageSource messageSource;
public void setMessageSource(MessageSource ms){
this.messageSource = ms;
}
// ......
}
Then your test would need to change as well:
@Test
public void validateViewLogin_NotValidLogin_returnsLoginPage() {
MockHttpServletRequest request = new MockHttpServletRequest();
Person person = new Person();
person.setFirstName("John");
person.setPassword("123");
isUserValid = false;
LogInController controller = new LogInController();
// Inject mock user service into controller
UserManagerService mockUserService = mock(UserManagerService.class);
/** ADDED **/
MessageSource ms = mock(MessageSource.class);
controller.setUserManagerService(mockUserService);
/** ADDED **/
controller.setMessageSource(ms);
// Configure mock user service to accept the person
when(mockUserService.validateUserLogin("John", "123")).thenReturn(
isUserValid);
/** ADDED **/
when(ms.getMessage("login.user.fail", new String[] {" ", "" }).thenReturn("message");
// Attempt the validation
ModelAndView mav = controller
.validateViewLogin(person, result, request);
// Check the result
assertEquals("login", mav.getViewName());
}
Just free handing this, so make sure I don't have any typos! Essentially you try the MessageSource as you did your UserManagerService, it's just an interface after all and can be mocked exactly the same way.