How to mock Hibernate Query.list() using Mockito

11,784

In my opinion there are two approach:

First: Create mock on SessionFactory like this

@Mock
private SessionFactory hibernateSessionFactory;

@Before
public void beforeTest(){
    MockitoAnnotations.initMocks(this);
}

@Test
public void testGetProduct() throws ProductException {
     //then mock all you need from hibernateSessionFactory
     Session session = Mockito.mock(Session.class);
     Query query = Mockito.mock(Query.class);

     Mockito.when(hibernateSessionFactory.getCurrentSession()).thenReturn(session);
     Mockito.when(session.createQuery("FROM com.esp.dao.entity.Product P WHERE P.isbn13 = :isbn13")).thenReturn(query);

     List<Product> productList = new ArrayList<>(1);
     Mockito.when(query.list()).thenReturn(productList);

Second: You should create instance of SessionFactory

private SessionFactory hibernateSessionFactory;

@Before
public void beforeTest(){
    hibernateSessionFactory = Mockito.spy(new ConstructorForSessionFactory ());
}
Share:
11,784

Related videos on Youtube

Sumit
Author by

Sumit

Updated on June 04, 2022

Comments

  • Sumit
    Sumit almost 2 years

    This is my class which need to be tested:

    @Repository
    @Transactional
    public class ProductDAOImpl implements ProductDAO {
    
    private static final Logger logger = Logger.getLogger(ProductDAOImpl.class);
    
    @Autowired
    private SessionFactory hibernateSessionFactory;
    
    
    @Override
    public ProductDTO getProduct(String isbn) throws ProductException {
        ProductDTO productDTO = new ProductDTO();
        Product product = getProductFromDb(isbn);
        BeanUtils.copyProperties(product, productDTO);
        return productDTO;
    }
    
    private Product getProductFromDb(String isbn) throws ProductException{
        Session session = this.hibernateSessionFactory.getCurrentSession();
    
    
        String hql = "FROM com.esp.dao.entity.Product P WHERE P.isbn13 = :isbn13";
        Query query = session.createQuery(hql);
        query.setParameter("isbn13",isbn);
    
    
        List<Product> productList = query.list();  // Want to mock this call
        if(productList.size() ==1)      
            return productList.get(0);
        else if(productList.size() >1)
            // throw new ProductException("Cannot return product. Multiple products found.", HttpServletResponse.SC_NOT_FOUND);
            throw new ProductException("Cannot return product. Multiple products found.");
        else if(productList.size() == 0){
            throw new ProductException("Cannot return product. No products found.");
        }
        return null;
    
    }
    

    I want to mock the query.list() method. This is what I have tried so far but getting exception: Type 'SessionFactory' is an interface and it cannot be spied on.

    @RunWith(MockitoJUnitRunner.class)
    public class TestProductDaoImpl {
    
    @Spy
    private SessionFactory hibernateSessionFactory;
    @InjectMocks
    private ProductDAOImpl productDAOImpl;
    
    @Test
    public void testGetProduct() throws ProductException {
    
        Session session = this.hibernateSessionFactory.getCurrentSession();
    
        String hql = "";
        Query query = session.createQuery(hql);
        Query spy = Mockito.spy(query);
        List<Product> productList = getProductList();
        doReturn(productList).when(spy).list();
    
        productDAOImpl.getProduct("abc");
    
    
    }
    

    I can mock the getProductFromDb(). But in that case there is no need to write a test case for that as the maximum part of the class is getting mocked.

  • Sumit
    Sumit almost 8 years
    I am sorry. I just edited my question. I need to mock the Query.list() method. For that in my test class I need to create a valid Query object & then mock it. But here I am unable to mock the Query object.
  • Evgeniy K.
    Evgeniy K. almost 8 years
    @Sumit Pal. You don't have error 'Type 'SessionFactory' is an interface and it cannot be spied on' and problem with only 'query.list()'?
  • Sumit
    Sumit almost 8 years
    I have that error. By applying your solution 1 it solved & now I am getting NullPointerException at line session.createQuery(hql);
  • Sumit
    Sumit almost 8 years
    Thanks!!. I was not aware that we can mock like Mockito.mock(Session.class); I thought we have to pass a valid object of Session in Mockito.mock(). :)