在Spring中为测试目的配置特定的内存数据库



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

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

MySQLH2驱动在pom.xml,像这样:

<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")注释测试类

另一种方法是将注释@AutoConfigureTestDatabase添加到测试类中。我的测试通常是这样的:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
public class MyRepositoryTest {
    @Autowired
    MyRepository repository;
    @Test
    public void test() throws Exception {
        // Tests...
    }
}

注意,需要在pom.xml文件中添加嵌入式数据库依赖项。对于嵌入式数据库,此注释是不必要的,即使仅在pom文件中添加依赖项也可以工作。

使用@SpringBootTest魔法,您只需要做以下两个更改。

  1. 在pom.xml中添加'h2'测试依赖项
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>
  • 使用@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—[main]beddedDataSourceBeanFactoryPostProcessor:替换dataSource内置版本的数据源bean

    2019-04-26 13:13:34.199 INFO 28627—[main]defaultlistablebeanfactory:覆盖bean定义for数据源

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

    注意:我仍然有'spring-jpa'属性定义在'应用程序。属性,我不使用任何配置文件。@AutoConfigureTestDatabase将覆盖现有的jpa配置与测试默认AutoConfigureTestDatabase.Replace。

    最简单的解决方案:

    1)在src/main/resources有应用程序。属性(生产配置):

    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
    

    和应用程序测试。

    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("test")注释你的测试类。

    对我来说很有魅力。

    @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")添加到您的测试中)。

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

    Spring (Boot) Profile机制是一个非常强大的工具,它的作用范围远远超出了"在测试时和运行时之间交换设置"。虽然,很明显,正如演示的那样,它也可以这样做:)

    这个解决方案支持开发和测试的通用设置。基于此解决方案:覆盖默认的Spring-Boot应用程序。属性设置在Junit Test中

    1. 应用程序。src/main/resources/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
    
  • 测试。properties (src/main/resources/application.properties),其中覆盖并添加了application.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
    
    pom.xml中设置H2和Postgre数据库
          <!-- h2 -->
          <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
          </dependency>
        <!-- postgress -->
          <dependency>
             <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
          </dependency>
    
  • 测试类:
  •     @RunWith(SpringRunner.class)
        @SpringBootTest
        @TestPropertySource(locations = "classpath:test.properties")
        public class ModelTest { 
        }
    

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

    1. employeemanagerApp -我的SpringApplication主类
    2. employeemanagerIntTests -我有我的黄瓜测试

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

    解决方案:在我的employeemanagerApp模块中,src/main/resources我放置了应用程序。以下内容的属性

    #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我放置应用程序。以下内容的属性

    #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)
    

    在构建中。gradle文件i添加了H2依赖

    testImplementation 'com.h2database:h2:1.4.200'
    

    所以当我运行测试时,H2是活动的,所有的创建、更新、读取和删除测试都是成功的

    相关内容

    • 没有找到相关文章

    最新更新