Search code examples
javahibernateunit-testingdao

Hibernate DAO Unit Testing Simple Fetch


I am very new to API development in Java and would like to create a proper unit test for my DAO Java class. The project uses Hibernate and the class fetches data from a MySQL database, returns it in a JSON format for a GET request.

I'm not sure how to write the unit test, if anyone could help I'd appreciate it.

public class LabelDAO extends AbstractDAO<LabelEntity> {

    public LabelEntity findLabelByLabelId(final String labelId) {
        final String query = "SELECT l FROM LabelEntity l WHERE l.labelId = :labelId";
        return getEntityManager().createQuery(query, LabelEntity.class).setParameter("labelId", labelId).getSingleResult();
    }
}

Solution

    1. First add junit library and hamcrest

      <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <version>4.13.2</version>
       <scope>test</scope>
      </dependency>
      
      <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest-all</artifactId>
       <version>1.3</version>
       <scope>test</scope>
      </dependency>
      
    2. For test sql query I use memory database H2 Add H2 JDBC Driver from Maven dependency:

      <dependency>
       <groupId>com.h2database</groupId>
       <artifactId>h2</artifactId>
       <version>2.1.214</version>
       <scope>test</scope>
      </dependency>
      
    3. Use database migrations library for create mock data. I advise you use database migration library for project. For example flyway or liquibase. I selected flyway for sample. Add from Maven dependency:

      <dependency>
       <groupId>org.flywaydb</groupId>
       <artifactId>flyway-core</artifactId>
       <version>8.5.13</version>
      </dependency>
      

    3.1 Create migration directory src/main/resources/db/migration/test. 3.2 Create sql script file. V1__Create_label_table.sql and set sql commands:

    CREATE TABLE label (
       id bigint not null,
       name varchar(100) not null
    );
    
    INSERT INTO label (id, name) values (1, 'My label');
    

    And need separately setting your entity manager for test...

    Sample test:

    @Test
    public void test() {
    
        Flyway flyway = Flyway.configure()
                .locations("classpath:/db/migration/test")
                .baselineOnMigrate(true)
                .dataSource("jdbc:h2:~/mem", "test", null)
                .load();
    
        flyway.clean();
        flyway.migrate();
    
    
        LabelDao labelDao = new LabelDao();
        labelDao.findLabelByLabelId("1");
        assertThat(labelDao.findLabelByLabelId("1").getName(), equalTo("My label"));
    
    }
    

    If you use spring you can use JpaRepository.

    For example:

    public interface LabelRepository extends JpaRepository<LabelEntity, Long> {
    }
    

    And replace code:

    @Service
    public class LabelDao {
    
        @Autowired
        private LabelRepository labelRepository;
    
        public Optional<LabelEntity> findLabelByLabelId(final Long labelId) {
            return labelRepository.findById(labelId);
        }
    }
    

    Sample test:

    @SpringBootTest
    class DemoApplicationTests {
    
        @Autowired
        private LabelDao labelDao;
    
        @Test
        public void test()  {
            labelDao.findLabelByLabelId(1L);
            assertThat(Objects.requireNonNull(labelDao.findLabelByLabelId(1L).orElse(null)).getName(), equalTo("My label"));
        }
    }