当前位置: 首页 > 知识库问答 >
问题:

Hibernate隔离集成测试

岳玉书
2023-03-14

我对hibernate有点陌生,所以我从一些简单的东西开始。

根据F.I.R.S.T测试原则,单元测试必须是I-隔离的。我试图使用@transactional注释将其应用于存储库层(Hibernate\JPA)的集成测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = RepositoryConfig.class)
@Transactional
public class EmployeeRepositoryTest extends AbstractRepositoryTest {    
    @Autowired
    private IEmployeeRepository employeeRepository;    
    @Test
    public void saveTest() {
        Employee expectedEmployee = buildEmployee(1, "Parker");
        employeeRepository.save(expectedEmployee);
        Employee actualEmployee = employeeRepository.findById(1);
        assertEquals(expectedEmployee, actualEmployee);
    }
    private Employee buildEmployee(long id, String name) {
        Employee employee = new Employee();
        employee.setId(id);
        employee.setName(name);
        return employee;
    }
}

但是,只要在一个事务中执行两个方法,hibernate实际上并不执行它们(据我所知)--至少日志中没有insert行。

INSERT INTO employee (employee_id, employee_name) VALUES (1, 'name');

我看到了一个自带EntityManager并调用其flush()方法的解决方案。但我不喜欢它,因为我试图在不绑定Hibernate\JPA的情况下编写测试。

我还尝试了不同的flushmode,但也没有帮助。

Q1:有没有办法让Hibernate在Repository的方法被调用后立即运行查询?

@Entity
@Table(name = "employee")
public class Employee {    
    @Id
    @Column(name = "employee_id")
    private long id;        
    @Column(name = "employee_name")
    private String name;
    // the rest required things (constructor, getters/setters and etc)
}

和RepositoryConfig:

@Configuration
@EnableTransactionManagement
@ComponentScan("org.my.package")
public class RepositoryConfig {    
    @Bean
    public DataSource getDataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .build();
    }    
    @Bean
    public JpaTransactionManager transactionManager() {
        return new JpaTransactionManager();
    }    
    @Bean
    @Autowired
    public HibernateTemplate getHibernateTemplate(SessionFactory sessionFactory) {
        return new HibernateTemplate(sessionFactory);
    }    
    @Bean
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(getDataSource());
        sessionFactory.setPackagesToScan("org.my.package.model");
        sessionFactory.setHibernateProperties(getHibernateProperties());
        return sessionFactory;
    }    
    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "H2Dialect");
        properties.put("hibernate.show_sql", true);
        return properties;
    }
}

共有1个答案

年文柏
2023-03-14

您别无选择,只能与实体管理器交互以使这些测试按您的预期工作--不触发刷新(这可以通过在存储库上调用saveandflush(..)方法而不是仅调用save(..)来实现),而是清除第一级缓存:

https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/jparepository.html#saveandflush-s-

@Test
public void saveTest() {
    Employee expectedEmployee = buildEmployee(1, "Parker");

    //call save and flush for immediate flush.
    employeeRepository.saveAndFlush(expectedEmployee);

    //now you will need to clear the persistence context to actually
    //trigger a load from the database as employee with id 1 is already
    //in the persistence context. 

    //without the below you will not see a db select
    entityManager.clear();

    Employee actualEmployee = employeeRepository.findById(1);
    assertEquals(expectedEmployee, actualEmployee);
}

清除持久性上下文的另一种方法是使用原始JDBC读取更新的行。

但我不喜欢它,因为我试图在不绑定Hibernate\JPA的情况下编写测试。您正在测试一个在Hibernate\JPA中实现的持久性机制,而您的存储库只是一个抽象,允许您避免直接调用它,所以这似乎有点荒谬。

 类似资料:
  • 完成了818个集成测试,0在104001ms运行1个spock测试时失败...失败:CreditServiceSpec groovy.lang.groovyRuntimeException:未能调用构造函数:public org.codehaus.groovy.grails.test.support.grailstestautoWirer(org.springframework.context.a

  • 问题内容: 我一直在尝试: 关于我的服务方式,但spring抱怨说: 我该如何解决? 问题答案: 此实现不解决清理问题,我已经实现了类似的解决方案,但也解决了清理问题。可以在以下位置找到该解决方案:http : //shahzad-mughal.blogspot.com/2012/04/spring-jpa-hibernate-support-for- custom.html

  • 主要内容:集成测试背后的原因,集成测试技术,集成测试方法,集成测试指南集成测试是单元测试后软件测试过程的第二个层次。在此测试中,软件的单元或单个组件在组中进行测试。集成测试级别的重点是在集成组件或单元之间交互时暴露缺陷。 单元测试使用模块进行测试,这些模块在集成测试中进行组合和测试。该软件使用许多软件模块开发,这些软件模块由不同的编码器或程序员编码。集成测试的目标是检查所有模块之间通信的正确性。 集成测试背后的原因 虽然软件应用程序的所有模块已经在单元测试中进行了测

  • 设计 集成测试包括 3 个模块:测试用例、测试环境以及测试引擎。 测试用例 用于定义待测试的 SQL 以及测试结果的断言数据。 每个用例定义一条 SQL,SQL 可定义多种数据库执行类型。 测试环境 用于搭建运行测试用例的数据库和 ShardingSphere-Proxy 环境。 环境又具体分为环境准备方式,数据库类型和场景。 环境准备方式分为 Native 和 Docker,未来还将增加 Emb

  • 主要内容:数据库设置:,Hibernate的配置:,环境设置:,Hibernate 类:,动作类:,创建视图文件:,Struts 配置:Hibernate是一个高性能的对象/关系持久性和查询服务许可下的开源GNU通用公共许可证(LGPL),并免费下载。在这一章中,我们要学习如何实现Struts2与Hibernate集成。如果你不熟悉与Hibernate,那么可以查看我们的Hibernate教程。 数据库设置: 在本教程中,我会使用“struts2_tutorial”MySQL数据库。我连接到我的

  • 组织。springframework。豆。工厂BeanCreationException:创建名为“searchController”的bean时出错:自动连线依赖项的注入失败;嵌套的异常是org。springframework。豆。工厂BeanCreationException:无法自动关联字段:com。辛迪娅。Spring服务学生服务公司。辛迪娅。mvc。搜索控制器。学生服务;嵌套的异常是or