在spring boot中进行单元测试之前,通过data.sql文件向h2数据库中插入数据

Posted

技术标签:

【中文标题】在spring boot中进行单元测试之前,通过data.sql文件向h2数据库中插入数据【英文标题】:Insert data in h2 database through data.sql file before performing unit testing in spring boot 【发布时间】:2020-06-05 14:28:13 【问题描述】:

我想在 Spring Boot+JPA 中进行单元测试。为此,我创建了配置文件来为 dataSource、所有休眠属性、entityManagerFactory 和 transactionManager 创建 bean。一切顺利。表是由模型类创建的。但现在我想在数据库的所有表中插入数据以通过 data.sql 文件进行测试。 我将 data.sql 文件保存在 src/main/resources 中,但它没有加载文件。 那么在开始单元测试之前如何在 h2 数据库中加载数据。

这是我的配置文件 -


import java.util.Properties;

import javax.sql.DataSource;

import org.hibernate.cfg.Environment;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@Configuration
@EnableJpaRepositories(basePackages = "base_package_name")
@EnableTransactionManagement
public class JPAConfig 

    @Bean
    public DataSource dataSource() 
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUrl("jdbc:h2:mem:myDb;DB_CLOSE_DELAY=-1");
        /*dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
        dataSource.setUrl("jdbc:hsqldb:mem:testdb");*/
        dataSource.setUsername("sa");
        dataSource.setPassword("");

        return dataSource;
    

    private Properties hibernateProperties() 
        Properties properties = new Properties();
        properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
        properties.put("hibernate.hbm2ddl.auto", "create");
        properties.put("hibernate.show_sql", "true");
        properties.put("hibernate.format_sql", "false");
        return properties;
    

    @Bean(name="entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean()

        LocalContainerEntityManagerFactoryBean lcemfb
            = new LocalContainerEntityManagerFactoryBean();

        lcemfb.setDataSource(this.dataSource());
        lcemfb.setPackagesToScan(new String[] "Package_to_scan");

        HibernateJpaVendorAdapter va = new HibernateJpaVendorAdapter();
        lcemfb.setJpaVendorAdapter(va);

        lcemfb.setJpaProperties(this.hibernateProperties());

        lcemfb.afterPropertiesSet();

        return lcemfb;

    


    @Bean
    public PlatformTransactionManager transactionManager()

        JpaTransactionManager tm = new JpaTransactionManager();

        tm.setEntityManagerFactory(
            this.entityManagerFactoryBean().getObject() );

        return tm;

    

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
        return new PersistenceExceptionTranslationPostProcessor();
    


【问题讨论】:

howtodoinjava.com/spring-boot2/h2-database-example 可能有帮助 您好,我写了一个答案,但如果您可以发布与您的配置相关的代码部分,将会很有帮助。 【参考方案1】:

根据 *** 上的另一个问题,您可以通过在测试中添加 @Configuration 类来初始化数据库,如下所示:

@Configuration
public class DatabaseTestConfig 
    @Bean
    public DataSource dataSource() 
        return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:schema.sql")
            .addScript("classpath:test-data.sql")
            .build();
    

请注意,以上内容不使用 JPA,因此您可能需要根据自己的目的对其进行调整,但它应该很好地提示您如何在 JPA 中进行操作。

然而,我的偏好倾向于在每个测试中使用 @Sql 注释,初始化数据然后清理它。虽然这意味着更多的重复,这通常很糟糕,但它有助于确保测试始终从头开始运行。

参考文献

How to initialize in-memory HSQLDB using script via Spring https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/testing.html#spring-testing-annotation-sql https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-initialize-a-database-using-hibernate

【讨论】:

我刚刚添加了用于单元测试的配置文件。你能参考一下吗... 我去看看。同时,我建议使用spring.jpa.hibernate.ddl-auto。另外,请注意,在entityManagerFactoryBean 中,您没有使用 bean 配置中定义的 DataSource,而是创建了它的另一个实例。在entityManagerFactoryBean 方法中添加DataSource 参数并将lcemfb.setDataSource(this.dataSource()); 替换为lcemfb.setDataSource(dataSource);。我认为它不会解决您的问题,但它允许您将 DataSource 配置拆分为单独的文件以进行测试。

以上是关于在spring boot中进行单元测试之前,通过data.sql文件向h2数据库中插入数据的主要内容,如果未能解决你的问题,请参考以下文章

怎样使用Spring Boot项目的单元测试?

Spring Boot 项目在 IDEA 中 进行单元测试

Spring Boot 不运行单元测试

Spring Boot 中的单元测试

禁用 Spring Boot 启动器 Cassandra 进行单元测试

[翻译]使用Spring Boot进行单元测试