在Spring Boot单元测试之前,通过data.sql文件向h2数据库插入数据

4

我想在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();
    }
}


https://howtodoinjava.com/spring-boot2/h2-database-example/ 可能会有所帮助。 - seenukarthi
嗨,我写了一个答案,但如果您能发布与您的配置相关的代码部分,那将会很有帮助。 - Filippo Possenti
1个回答

6
根据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注释来初始化数据,然后清理它。虽然这意味着会有更多的重复,但它有助于确保测试始终从干净的状态运行。
参考:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接