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

标签 java spring-boot h2 spring-boot-test h2db

我想在 spring boot+ JPA 中执行单元测试。为此,我创建了配置文件来为 dataSource、所有 hibernate 属性、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();
    }
}

最佳答案

根据 StackOverflow 上的另一个问题,您可以通过添加 @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
  • 关于java - 在spring boot中进行单元测试之前,通过data.sql文件在h2数据库中插入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60333899/

    相关文章:

    java - Spring Boot JacksonTester 自定义序列化程序未注册

    java - Spring Boot 中过滤器链中的自定义数据源

    spring-boot - 如何使用 kotlin.logging 记录堆栈跟踪?

    java - 将 h2 数据库实现到现有的 spring-boot 应用程序

    java - 无法使用JPA在H2中创建表和加载数据

    java - Maven - 如何获取所有依赖的 Artifact

    java - 在 Android 中运行的应用程序中存储数据的最佳选择 [SQLite 之前]

    java - Spring Security - antMatcher 的 POST 方法(不是 antMatchers)

    java - 如何在没有 session 属性的情况下将对象从 jsp 页面传递到 servlet

    java - JPA 问题,当我调用 : em. persist(obj); 时 `Referential integrity constraint violation Exception`