java - 使用 Junit 在 hbm2dll 上测试 HQL 查询

标签 java hibernate junit spring-data-jpa

如何使用 JUnit 测试来测试 HQL 查询?

我已经映射了实体类:

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

代表域对象:

public class DomainObject {
     //some attributes
}

我的域对象也有存储库接口(interface):

 public interface DomainObjectRepository {

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

该接口(interface)实现于

 @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. 创建测试对象放入数据库
  2. 从数据库检索对象
  3. 比较对象

我已经使用 import.sql 设置了 hbm2dll 来创建和填充我的数据库,但是如何通过调用方法 findByDomainObjectId 从 Junit 测试访问它?

最佳答案

单元与集成

首先您需要问一件事:

  1. 您想要单元测试还是集成测试

单元测试运行速度快(即几毫秒),而且是单一的 - 这意味着它不接触数据库。

集成测试比较繁重,如果是数据库测试,会涉及数据库。

虽然通常最好创建单元测试,但在您的情况下,您似乎想要进行集成测试 - 您实际上想要测试对数据库的调用并检查查询是否按照您的想法进行。

何时加载数据

我建议在集成测试中不要使用 import.sql 预加载数据(或者至少仔细考虑这是否是您想要的)。原因是,随着测试套件的增长,您将需要数据库处于一种状态用于测试 A,另一种状态用于测试 B,依此类推,您很快就会陷入这样的情况:具有不兼容的状态。

如果通过 SQL 加载太多数据,您的测试也会变慢。

我的建议是:尝试在测试中创建/操作数据。

如何测试

如何测试它取决于您在生产中如何加载 hibernate 。从您所显示的代码来看,我相信您可能正在使用依赖项注入(inject)机制来启动 hibernate 的 EntityManager (或 SessionFactory),例如 Spring。

如果是这种情况,您可以使用spring to configure you integration test 。 这里的主要建议是:

  1. 使用回滚,以便在测试之间不存储数据(保证测试独立性)
  2. 随着测试套件的增长,创建一个抽象类来保存配置,例如公开 EntityManager/sessionFactory。您所有的集成测试只需要扩展此类,注入(inject)存储库(在您的示例中,将 DomainObjectRepositoryImpl 注入(inject)到测试中)并运行您需要测试的方法。

下面是我的一个非常简单的抽象测试(在我的例子中我使用的是 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);
}
}

关于java - 使用 Junit 在 hbm2dll 上测试 HQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39141499/

相关文章:

java - ShortcutInfo 和 ShortcutInfoCompat 之间的区别?

mysql - Spring Boot Data JPA - 如何获取特定id的数据

hibernate - 如何让 Hibernate 过滤器在 JPA 中工作?

spring-boot - Spring Boot 应用程序找不到 SQLite jdbc 驱动程序类

java - 如何模拟 sun jersey 客户邮寄电话?

junit - @Entity Pojos 应该被测试吗?

java - 上下文初始化失败 - Broadleaf Commerce - 发送订单确认电子邮件

java - 战舰代码不起作用

java - 使用 JAXB 将 XML 文件解析为流

Java 构造函数被多次调用