2016-08-25 43 views
0
hbm2dll

如何測試使用JUnit測試HQL查詢?測試HQL查詢上使用JUnit

我已經映射實體類:

@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實體庫看起來是這樣的:

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. 創建測試對象投入DB
  2. 從數據庫中檢索對象
  3. 比較對象

我已經設置好的了import.sql一個hbm2dll創建和填充我的數據庫,但我如何通過調用方法findByDomainObjectId從Junit測試訪問它?

回答

1

單位VS集成

首先有你需要問一兩件事:

  1. 你想要的單元測試或集成測試

的單元測試運行速度很快(即毫秒),並且是單一的 - 意味着它不會觸及數據庫。

集成測試是較重的,並且在數據庫測試的情況下,將觸摸分貝。

雖然通常優選創建單元測試,你的情況,似乎你想要一個集成測試 - 你真的想呼叫測試到數據庫,並檢查查詢做什麼,你認爲它。

當加載數據

我建議,在你的集成測試你不預裝與import.sql數據(或者至少非常仔細一想,如果這是你想要的)。這樣做的原因是,隨着測試套件的增長,你需要在數據庫中的一個狀態測試A,測試B中的另一狀態,等等,你會很快的情況下結束了在那裏你會有不相容的狀態。

你還會落得慢的測試,如果你通過SQL加載過多的數據。

我的建議是:儘量在您的測試創建/操縱數據。

如何測試

如何來測試它取決於你如何加載休眠生產。根據你所顯示的代碼判斷,我相信你可能會使用依賴注入機制來啓動hibernate的EntityManager(或SessionFactory),就像Spring一樣。

如果是這樣,您可以使用spring to configure you integration test。 這裏的主要建議是:

  1. 使用回滾,使數據不存儲測試之間(保證測試的獨立性)
  2. 作爲測試套件的增長,創建包含配置和,如一個抽象類,公開EntityManager/sessionFactory。你所有的集成測試只需要擴展這個類,注入庫(在你的例子中,注入DomainObjectRepositoryImpl到測試中)並運行你需要測試的方法。

下面是一個非常簡單的抽象測試我(對我來說,我使用一個會話):

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然後在安裝時,用數據填充它,這種方式測試只與DB結構綁定,而不是數據裏面

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 
}