2016-08-25 42 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 
}