Kshitiz Bathwal
Kshitiz Bathwal

Reputation: 87

How to test Hibernate Configuration Class which is Java Annotated in SpringBoot using Mockito?

I am working on a SPringBoot+Hibernate+REST project using Mysql DB. I want to know how I can Unit Test the below class. I have been told that Mocking is the best way to go about it. I think this is related to Database Mock Testing. I have no clue even after researching a lot online. Can someone guide me how I should test it. If I have DAO classes in my project which use thse db connections, do I still need to test the below Class? I even have RestController Class which needs to be tested. Please guide me how I should go ahead with this. I am a beginner.

DBConfiguration.Java

package com.youtube.project.config;

import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;

@PropertySource(value = { "classpath:application.properties" })
@Configuration
@EnableTransactionManagement
public class DBConfiguration {

    @Value("${jdbc.driverClassName}")
    private String driverClass;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;
    @Value("${hibernate.dialect}")
    private String dialect;

    @Bean
    public DataSource getDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource(url,username,password);
        dataSource.setDriverClassName(driverClass);
        return dataSource;
    }

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
        factory.setDataSource(getDataSource());
        factory.setHibernateProperties(hibernateProperties());
        factory.setPackagesToScan(new String[] {"com.youtube.project"});
        return factory;
    }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", dialect);
        properties.put("hibernate.hbm2ddl.auto", "update");
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.format_sql", "true");
        return properties;
    }

    @Bean
    @Autowired
    public HibernateTransactionManager transactionManager(SessionFactory factory) {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(factory);
        return transactionManager;
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
          LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
          em.setDataSource(getDataSource());
          em.setPackagesToScan(new String[] { "com.youtube.project.model" });     
          JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          em.setJpaVendorAdapter(vendorAdapter);
          return em;
       }
} 

Upvotes: 2

Views: 1356

Answers (1)

Urosh T.
Urosh T.

Reputation: 3814

I want to know how I can Unit Test the below class

Well, it is kinda complicated because your configuration class actually makes connections to the database so this class is not actually very desirable for "Unit Testing" per-se.

Because UNIT TESTING is a level of software testing where individual units/ components are tested (unit is the smallest testable part of your application). It usually has one or a few inputs and usually a single output.

IMHO I would put this as Integration testing because you would need to connect to a database.

How to approach testing this:

TL;DR - Don't bother writing an explicit test for this class.

By running a @SpringBootTest on your main class, your class should get tested as a side effect.

Explanation:

It makes little sense to test this class explicitly because you will basically test:

  • Have the beans been created
  • Are the @Value fields populated with values
  • Is the connection to the database established

From these 3 things, only point #3 is valid to test, the first two are tested by Spring developers when they were writing the framework. That being said, connecting to the database is more of an integration test than a unit test. If you want to test that, you can use an in-memory database like H2, it can be configured to run on tests only.

I have DAO classes in my project which use thse db connections, do I still need to test the below Class? I even have RestController Class which needs to be tested.

Spring has a great support for testing application slices (parts of your app, e.g: one class at a time or a class + it's dependencies).

Specifically:

  • for DAO class, check out @DataJpaTest and TestEntityManager class.
  • For controller classes, use @WebMvcTest and MockMvc class.

These things are designed to make your testing easier with spring boot. For some basic info, you can check out this article.

Hope this helps

Upvotes: 2

Related Questions