0

Im writing unit test cases of a controller file

LoginController.java

CustomerDao customerdao = new CustomerDao();
    Customer customer = new Customer();
    InvoiceDao invoceDao = new InvoiceDao();
    DashboardDao dashboarddao = new DashboardDao();
    private static final Logger log = LogManager.getLogger(LoginController.class);
    LoginDao loginDao = null;

    @RequestMapping(value = "/login.do", method = RequestMethod.POST)
    public ModelAndView login(HttpServletRequest req, HttpServletResponse res)
            throws SQLException, PropertyVetoException {
        boolean isAlpha = false;
        boolean isAdmin = false;
        boolean checkRoleAssigned = false;
        String password = req.getParameter("password");
        String staffId = req.getParameter("username");
        loginDao = new LoginDao();
        
        Admin admin = loginDao.getAdminDetails(staffId, password);
        System.err.println("\n\nadmin -> " + admin);
        if (admin != null) {
            int roleId = loginDao.isRoleExistInRbac(admin.getStaffId());
            checkRoleAssigned = loginDao.checkUserAccess(admin.getStaffId());
            isAlpha = loginDao.checkUserAccessInRbac(roleId);
            isAdmin= loginDao.checkAdmin(admin.getUserId());
            admin.setAdminStatus(loginDao.checkAdmin(admin.getUserId()));
            if (isAdmin) {
                HttpSession session = req.getSession();
                session.setMaxInactiveInterval(120 * 20);
                session.setAttribute("admin", admin);
                
              
                return new ModelAndView("redirect:dashboardView.do");//prevoiusly it was redirect:listInvoice.do
                

            } else {

                if (checkRoleAssigned) {
                    if (isAlpha) {
                        HttpSession session = req.getSession();
                        session.setMaxInactiveInterval(120 * 20);

                        session.setAttribute("admin", admin);

                        //return new ModelAndView("redirect:listInvoices.do");
                        return new ModelAndView("redirect:dashboardView.do");
                    } else {
                        return new ModelAndView("index", "errorMessage", " Sorry , You dont have any module access.");
                    }

                } else {
                    return new ModelAndView("index", "errorMessage", " Sorry , You are not a authorised person.");
                }

            }
        }
        return new ModelAndView("index", "errorMessage", " Username or password incorrect.");
    }

and this is the test case for this method

LoginControllerTest.java

@InjectMocks
    LoginController loginController;
    
    @Mock
    CustomerDao customerDao;
    
    @Mock
    Customer customer;
    
    @Mock
    InvoiceDao invoiceDao;
    
    @Mock
    DashboardDao dashboardDao;
    
    @Mock
    LoginDao loginDao;

    @Mock
    Admin admin;
    
    @Test
    void testLogin() throws Exception {
        
        MockHttpServletRequest request = new MockHttpServletRequest();
        MockHttpServletResponse response = new MockHttpServletResponse();
        
        request.setParameter("password", "pass");
        request.setParameter("username", "uname");

        when(loginDao.getAdminDetails(anyString(), anyString())).thenReturn(admin);
        
        assertNotNull(loginController.login(request, response));
    }

but the problem is it is not functioning as I expected and loginDao.getAdminDetails() is returning null. plus its throwing UnneccessaryStubbingException too.

when I try to initialize the Dao class by using mock() method I do get rid of the exception, but the thenReturn() remains non-functional. Could anyone suggest what am I doing wrong?

  • I dont think "LoginDao loginDao = null;" is going to help with Mocking. You need to create a Bean for LoginDao with '@Component' or some annotation and then '@Autowire' it in your rest controller instead of creating objects with new keyword – voucher_wolves Nov 19 '22 at 13:04
  • Did you inject loginDAO mock into controller? – Christoph Dahlen Nov 19 '22 at 13:05
  • Does this answer your question? [Why is my class not calling my mocked methods in unit test?](https://stackoverflow.com/questions/74027324/why-is-my-class-not-calling-my-mocked-methods-in-unit-test) – `loginDao = new LoginDao();`: `loginDao` is a new object, not your mock. Your mock is not used by your object at all. – knittl Nov 20 '22 at 17:16
  • `loginDao = new LoginDao();`: `loginDao` is a new object, not your mock. Your mock is not used by your object at all. `@Mock` does not magically make all instances to this type a reference to the mock. Please read the dupe for an in-depth explanation. – knittl Nov 20 '22 at 17:18

1 Answers1

0

Use MockitoAnnotations.initMocks(this); in your test setUp or use JUnit annotation based runner to init and inject the mocks.

Sabyrzhan
  • 175
  • 2
  • 16
  • I did what you told but it still isn't working – Rishi Mudaliar Nov 20 '22 at 06:37
  • Ok, now i see. You are initializing logindao in method with this `loginDao = new LoginDao()` thus replacing mock instance. You should inject it with constructor or setter. But totally not instantiate at runtime. – Sabyrzhan Nov 21 '22 at 08:56