在Spring中配置特定的内存数据库以进行测试

时间:2015-08-14 02:31:07

标签: spring spring-boot spring-data spring-test spring-test-dbunit

如何配置我的Spring Boot应用程序,以便在运行单元测试时它将使用内存数据库,如H2 / HSQL,但是当我运行Spring Boot应用程序时,它将使用生产数据库[Postgre / MySQL]?

8 个答案:

答案 0 :(得分:49)

可以使用Spring配置文件。这将是一种特定的方式:

拥有特定于环境的属性文件:

<强> application.properties

spring.profiles.active: dev

<强> application-dev.properties

spring.jpa.database: MYSQL
spring.jpa.hibernate.ddl-auto: update

spring.datasource.url: jdbc:mysql://localhost:3306/dbname
spring.datasource.username: username
spring.datasource.password: password

<强> application-test.properties

spring.jpa.database: HSQL

pom.xml中同时拥有 MySQL H2 驱动程序,如下所示:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>test</scope>
</dependency>

最后但并非最不重要的是,使用@ActiveProfiles("test")注释测试类。

答案 1 :(得分:26)

另一种方法是将注释@AutoConfigureTestDatabase添加到测试类。 我的测试通常如下所示:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class MyRepositoryTest {

    @Autowired
    MyRepository repository;

    @Test
    public void test() throws Exception {
        // Tests...
    }
}

答案 2 :(得分:6)

@Sanjay有一种方法可以解决它,但我发现它令人困惑。您也可以只在生产时启用production配置文件,例如:

spring.jpa.hibernate.ddl-auto: update
spring.datasource.url: jdbc:mysql://localhost:3306/dbname
spring.datasource.username: username
spring.datasource.password: password

并且不要指定任何其他内容。如果在test范围内添加嵌入式数据库,它将在您的测试中可用。如果使用默认配置文件运行测试(无需任何自定义),它将无法找到任何数据库信息(因为这些信息存储在production配置文件中)。在这种情况下,它将尝试查找嵌入式数据库并为您启动它。如果由于某种原因需要进行更多自定义,那么您可以使用application-test.properties(您需要在测试中添加ActiveProfiles("test")

答案 3 :(得分:5)

使用maven进行构建时的简单解决方案:只需在application.properties下放置src/test/resources文件,然后根据需要进行编辑以进行测试。

Spring(引导)配置文件机制是一个非常强大的工具,在范围上超越了“在测试时间和运行时间之间交换设置”。虽然,显然,它也可以做到这一点:)

答案 4 :(得分:5)

最简单的解决方案:

1)在src / main / resources中有application.properties(生产配置):

spring.datasource.url=jdbc:mysql://localhost:3306/somedb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database-platform = org.hibernate.dialect.MySQL5Dialect

和application -test.properties与HSQL配置如:

spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.database = HSQL
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.HSQLDialect
spring.datasource.driverClassName = org.hsqldb.jdbcDriver
spring.datasource.url= jdbc:hsqldb:mem:scratchdb
spring.datasource.username = sa
spring.datasource.password =

2)如果你还没有,那么在pom.xml中添加HSQL依赖项。

3)使用@ActiveProfiles注释您的测试类(&#34; test&#34;)。

在我的案例中像魅力一样工作。

答案 5 :(得分:1)

此解决方案启用用于开发和测试的通用设置。基于此解决方案: Override default Spring-Boot application.properties settings in Junit Test

    src / main / resources / application.properties中的
  1. application.properties
    #common settings for DEVELOPMENT and TEST:
    ......
    ......

    ## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
    spring.datasource.url=jdbc:postgresql://localhost:5432/databasename
    spring.datasource.username=postgres
    spring.datasource.password=somepassword

    # The SQL dialect makes Hibernate generate better SQL for the chosen database
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
    spring.jpa.properties.hibernate.jdbc.time_zone=UTC

    # Hibernate ddl auto (create, create-drop, validate, update)
    spring.jpa.hibernate.ddl-auto = none
    spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
  1. test.properties (src / main / resources / application.properties),它覆盖并在应用程序.properties中添加属性:
    spring.datasource.url=jdbc:h2:mem:testdb;MODE=PostgreSQL
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=
    spring.jpa.hibernate.ddl-auto=update
    spring.h2.console.enabled=false

    H2和Postgre数据库的 pom.xml 中的
  1. 设置
      <!-- h2 -->
      <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
      </dependency>

    <!-- postgress -->
      <dependency>
         <groupId>org.postgresql</groupId>
         <artifactId>postgresql</artifactId>
      </dependency>

  1. 测试班中:
    @RunWith(SpringRunner.class)
    @SpringBootTest
    @TestPropertySource(locations = "classpath:test.properties")
    public class ModelTest { 

    }

答案 6 :(得分:0)

使用@SpringBootTest魔术,只需执行以下两项更改即可。

  1. 在pom.xml中添加“ h2”测试依赖项
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>
  1. 使用@ {AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
@AutoConfigureTestDatabase
public class SpringBootTest{

    @Autowired
    private RequestRepository requestRepository;
}

现在测试中使用的所有spring jpa bean /存储库都将使用h2作为备份数据库。

  

2019-04-26 13:13:34.198 INFO 28627 --- [主]   beddedDataSourceBeanFactoryPostProcessor:替换'dataSource'   嵌入式版本的DataSource bean

     

2019-04-26 13:13:34.199 INFO 28627 --- [主]   o.s.b.f.s.DefaultListableBeanFactory:覆盖bean定义   用于bean“数据源”

     

2019-04-26 13:13:36.194 INFO 28627-[[主要]   o.s.j.d.e.EmbeddedDatabaseFactory:启动嵌入式数据库:   url ='jdbc:h2:mem:2784768e-f053-4bb3-ab88-edda34956893; DB_CLOSE_DELAY = -1; DB_CLOSE_ON_EXIT = false',   username ='sa'

注意:我仍然在'application.properties'中定义了'spring-jpa'属性,并且我不使用任何配置文件。 @ AutoConfigureTestDatabase将使用测试默认值AutoConfigureTestDatabase.Replace覆盖现有的jpa配置。

答案 7 :(得分:0)

我有一个包含以下模块的多模块 Gradle SpringBootApplication

  1. employeemanagerApp - 我的 SpringApplication 主类
  2. employeemanagerIntTests - 我在哪里进行黄瓜测试

我的要求是在应用程序启动时使用 MySQL DB 并在我的 Cucumber 集成测试期间使用 H2

解决方案:在我的employeemanagerApp模块中,src/main/resources我放置了具有以下内容的application.properties

#My SQL Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/employeemanager
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update  spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

在集成测试模块 (employeemanagerIntTests) src/test/resources 中,我将 application.properties 放入以下内容

#H2 In-Memory DB Configuration
spring.datasource.url=jdbc:h2://mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.format_sql=true

在我的步骤定义类中,我只添加了这些注释

@CucumberContextConfiguration
@SpringBootTest(classes = SpringBootApplicationMainClass.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

在 build.gradle 文件中我添加了 H2 依赖

testImplementation 'com.h2database:h2:1.4.200'

因此,当我运行测试时,H2 处于活动状态,所有包含创建、更新、读取和删除的测试均成功