2016-08-25 3 views
0

Как я могу проверить запрос HQL с помощью тестов JUnit?тестирование запроса HQL на hbm2dll с помощью Junit

Я сопоставляются Entity Класс:

@Entity 
@Table(name = "DOE") 
public DomainObjectEntity { 
    //some attributes 
} 

, который представляет объекты домена:

public class DomainObject { 
    //some attributes 
} 

У меня также есть интерфейс хранилища для моих доменных объектов:

public interface DomainObjectRepository { 

    /** 
    * Gets entity by some attribute 
    * 
    */ 
    DomainObject getDomainObjectByObjectId(String objectId); 
} 

этот интерфейс реализован в

@Repository 
public class DomainObjectRepositoryImpl implements DomainObjectRepository { 

    @Inject 
    private DomainObjectEntityJPARepository entityRepository; 

    @Override 
    public DomainObjectgetDomainObjectById(String parcelId) { 
     //this converts my entity to domain object 
     return entityRepository.findByDomainObjectId(DomainObjectId.getStr()).getDomainObject(); 
    } 

} 

мой JPA Entity хранилище выглядит следующим образом:

public interface DomainObjectEntityJPARepository extends JpaRepository<DomainObjectEntity, String> { 
    /** 
    * get DomainObject with requested id 
    * 
    * @param objectId - objects id 
    * @return DomainObject 
    */ 
    @Query("some query to be tested") 
    DomainObjectEntity findByDomainObjectId(@Param("objectId") String objectId); 
} 

и, наконец, я хочу написать простой тест JUnit, чтобы проверить, если запрос на findByDomainObjectId возвращает правильный объект. Я думаю, что мой тест должен выглядеть следующим образом:

  1. создать тестовый объект поместить в БД
  2. получить объект из БД
  3. сравнения объектов

я выставиться в hbm2dll с import.sql создавать и заполнять мою БД, но как я могу получить к ней доступ из теста Junit, вызвав метод findByDomainObjectId?

ответ

1

блок против интеграции

Прежде всего есть одна вещь, которую вы должны спросить:

  1. Хотите тест блока или тест интеграции

Блок тест быстро (т. е. миллисекунды) для запуска и, ну, унитарно - это означает, что он не касается базы данных.

Тест интеграции более тяжелый, и в случае теста базы данных коснется дБ.

Хотя обычно желательно создавать модульные тесты, в вашем случае вам кажется, что вам нужен тест интеграции - вы действительно хотите протестировать вызов в базе данных и проверить, делает ли запрос то, что, по вашему мнению, он делает.

Когда загружать данные

Я хотел бы предложить, что в тесте интеграции не поджать данные с import.sql (или, по крайней мере, думаю, очень внимательно, если это то, что вы хотите). Причина этого в том, что по мере роста набора тестов вам понадобится база данных в одном состоянии для теста A, другого состояния для теста B и т. Д., И вы быстро окажетесь в ситуации, когда вы будете имеют несовместимые состояния.

Вы также получите более медленные тесты, если вы загрузите слишком много данных через SQL.

Мои рекомендации: попытаться создать/обработать данные в вашем тесте.

Как проверить

Как проверить это зависит от того, как вы загрузили в спящий режим в производстве. Судя по коду, который вы показали, я считаю, что вы можете использовать механизм инъекций Dependency для запуска EntityManager (или SessionFactory) hibernate, например Spring.

Если это так, вы можете использовать spring to configure you integration test. Основные предложения здесь будут:

  1. Использование отката, так что данные не сохраняются между тестами (гарантии тестом независимость)
  2. Как ваш набор тестов растет, создать абстрактный класс, который содержит конфигурацию и, например, выдает EntityManager/sessionFactory. Все ваши интеграционные тесты просто должны расширить этот класс, добавить репозиторий (в вашем примере, добавить DomainObjectRepositoryImpl в тест) и запустить метод, который вам нужно протестировать.

Ниже приведен очень простой абстрактный тест у меня есть (в моем случае я использую SessionFactory):

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.transaction.TransactionConfiguration; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={ 
     "/spring-SF-tests.xml", 
     "/spring-transaction.xml" 
}) 
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true) 
public abstract class HibernateAbstractTest extends AbstractTransactionalJUnit4SpringContextTests { 
@Autowired 
protected SessionFactory sessionFactory; 

public void setSessionFactory(SessionFactory sessionFactory){ 
    this.sessionFactory = sessionFactory; 
} 

public Session getSession(){ 
    return sessionFactory.getCurrentSession(); 
} 

public void save(Object object){ 
    getSession().save(object); 
} 

public void update(Object object){ 
    getSession().update(object); 
} 
} 
+0

спасибо, это на самом деле мне очень помогло! Однако я решил сделать модульные тесты, так как я только хотел проверить querry, предоставит решение, которое работало в секунду –

0

Так как я хотел проверить только запрос, правильное решение было @autowire JPArepository, а затем в настройках, заполнить его данными, таким образом тесты были связаны только с структурой БД, а не с данными внутри

public class EntityObjectJPARepositoryTest { 

    @Autowired 
    DomainObjectEntityJPARepository domainObjectRepo; 

    DomainObjectEntity entity; 

    @Before 
    public void Setup(){ 
      entity = new DomainObjectEntity() 
      //setup entity 
      domainObjectRepo.save(entity); 
     } 

     @Test 
     public void testfindByDomainObjectId(){ 
      DomainObjectEntity res = domainObjectRepo.findByDomainObjectId(objectid); 
      Assert.assertEquals(entity.getId(), res.getId()); 
     } 
    //everything else 
} 
Смежные вопросы