1

I'm trying to test My Spring controllers using Mockito, but I can't actually get how can I do that without making everything @Mock. Moreover test method returns me NullPointerException, as it can see no user and actually no user role at all. Is there a way to test my controllers somehow?

(Controller class)

@Controller
@SessionAttributes("user")
@RequestMapping("/login.htm")
public class LoginController{

    @Autowired
    private UserDao userDao;
    @Autowired
    private LoginValidator loginValidator;

    public LoginValidator getLoginValidator() {
        return loginValidator;
    }

    public void setLoginValidator(LoginValidator loginValidator) {
        this.loginValidator = loginValidator;
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @RequestMapping(method = RequestMethod.GET)
    public String getSendEmptyForm(ModelMap model, HttpServletRequest req) {
        req.getSession().invalidate();
        model.addAttribute("loginForm", new LoginForm());
        return "login";
    }

    @RequestMapping(method = RequestMethod.POST)
    public String postSubmittedForm(ModelMap model, @ModelAttribute("loginForm") LoginForm loginForm,
            BindingResult result, SessionStatus status) {
        //validate form
        loginValidator.validate(loginForm, result);

        if (result.hasErrors()) {
            return "login";
        } 

        User user = userDao.findByLogin(loginForm.getLogin());
        model.addAttribute("user", user);

        if (user.getRole().getName().equals("Admin")) {
            model.addAttribute("usersList", userDao.findAll());
            return "viewAllUsersPage";
        } 

        if (user.getRole().getName().equals("User")){
            return "userPage";
        }

        model.addAttribute("error", "Your role is not User or Admin");
        return "errorPage";
    }

}

And my testing class

@RunWith(MockitoJUnitRunner.class) 
public class LoginControllerTest {

    @InjectMocks
    private LoginController controllerUT = new LoginController();

    @Mock
    private ModelMap model;

    @Mock
    private LoginForm loginForm;

    @Mock
    private BindingResult result;

    @Mock
    private SessionStatus status;

    @Mock
    private LoginValidator validator;

    @Mock
    private UserDao userDao;

    @Mock
    private User useк;

    @Test
    public void testSendRedirect(){
        final String target = "login";
        String nextPage = controllerUT.postSubmittedForm(model, loginForm, result, status);
        assertEquals(target, nextPage);
    }

}
3
  • Please show stack trace for NullPointerException in your test method. Commented Feb 25, 2013 at 14:14
  • Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.365 sec <<< FAILURE! testSendRedirect(test.LoginControllerTest) Time elapsed: 0.343 sec <<< ERROR! java.lang.NullPointerException at spring.controller.LoginController.postSubmittedForm(LoginController.java:68) at test.LoginControllerTest.testSendRedirect(LoginControllerTest.java:55) Commented Feb 25, 2013 at 14:24
  • line 68: if (user.getRole().getName().equals("Admin")) { Commented Feb 25, 2013 at 15:11

1 Answer 1

3

First off you seem to be missing stubbing for loginForm.getLogin() and userDao.findByLogin(loginForm.getLogin()) and user.getRole().getName(). Without such stubbing, these methods called on a mock will return a default value (i.e. null).

So you may want to add :

when(loginForm.getLogin()).thenReturn(login);
when(userDao.findByLogin(login)).thenReturn(user);
when(user.getRole()).thenReturn(role);
when(role.getName()).thenReturn("Admin");

You will want to vary the return values for different tests. Depending on your implementation classes for User and Role, you could simply supply real instances. For a test that simulates the result to have errors you'll want to add this stubbing :

when(result.hasErrors()).thenReturn(true);

since otherwise the default false is returned.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.