Search code examples
javahibernatejunitpowermockpowermockito

Mockito Test Failed: Actually, there were zero interactions with this mock


Just wanna ask as I am stuck in the test cases and getting error as "Actually, there were zero interactions with this mock".

I have created an Dao Implementation class which is doing CRUD operation.

public class EmployeeDaoImpl implements EmployeeDao {
       @Override
        public void saveEmployee(EmployeeDetails employee) {

            Session session = HibernateUtil.getSessionFactory().openSession();
            Transaction transaction = session.beginTransaction();
            session.save(employee); 
            transaction.commit();
            session.close();

        }
    }

And for this above class I am building the test using Mockito. So for my above saveEmployee method Session, TRansaction I have made it as Mock object and now I need to check session , save method and transaction as well.

So I have written the Mockito code below:

/** * */

package sandeep.test;

import static org.junit.Assert.*;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;

import junit.framework.Assert;

import org.hibernate.Session;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import sandeep.DAO.EmployeeDao;
import sandeep.DAOImpl.EmployeeDaoImpl;
import sandeep.DAOImpl.HibernateUtil;
import sandeep.pojo.EmployeeDetails;
import static org.mockito.Mockito.*;


/**
 * @author sandeep
 *
 */
@RunWith(MockitoJUnitRunner.class)
public class EmployeeDaoImplTest {

    @Mock
    EmployeeDetails edt;
    @Mock
    Session session ;
    @Mock
    Transaction transaction;

    @InjectMocks
    EmployeeDaoImpl edi = new EmployeeDaoImpl();

    @Before
    public void setUp() throws Exception {
        //eimpl = new EmployeeDaoImpl();
        //emp= mock(EmployeeDao.class);
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testSaveEmployee(){
        edi.saveEmployee(getEmployeeDetails());
        // But here i am getting the error as zero interactions
        verify(session, times(1)).save(EmployeeDetails.class);  
    }

    public EmployeeDetails getEmployeeDetails(){

        edt = new EmployeeDetails();
        edt.setEname("sandeep");
        edt.setId(2);
        edt.setEnumber("hoi");
        return edt;

    }   
}

I have debugged the code and the code is passing onto all the breakpoints in my IDE and when I execute this the 3 values it will be added to the database but my test case will fail as there are zero interactions.


Solution

  • The Session mock in your test is not the same object used in EmployeeDaoImpl#saveEmployee

    Implement a constructor for EmployeeDaoImpl with a Session argument and use that argument in the saveEmployee() method. This allows your @InjectMocks to work as intended.

    @RunWith(MockitoJUnitRunner.class)
    public class MockitoTest {
    
        @Mock
        Session session;
    
        @InjectMocks
        EmployeeDaoImpl edi;
    
        @Test
        public void testSaveEmployee(){
            edi.saveEmployee();
    
            verify(session, times(1)).save();
        }
    }
    
    class Session {
        void save() {
            System.out.println("saving");
        }
    }
    
    interface EmployeeDao {
        void saveEmployee();
    }
    
    class EmployeeDaoImpl implements EmployeeDao {
        private Session session;
    
        public EmployeeDaoImpl(Session session) {
            this.session = session;
        }
    
        @Override
        public void saveEmployee() {
            session.save();
        }
    }