Configure specific in memory database for testing purpose in Spring

前端 未结 7 796
粉色の甜心
粉色の甜心 2020-12-07 13:19

How do I configure my Spring Boot application so that when I run unit tests it will use in-memory database such as H2/HSQL but when I run Spring Boot application it will use

相关标签:
7条回答
  • 2020-12-07 13:55

    Simplest solution:

    1) in src/main/resources have application.properties (production config):

    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
    

    and application-test.properties with HSQL config like:

    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) Add HSQL dependency in pom.xml if you don't have it already.

    3) Annotate your test class with @ActiveProfiles("test").

    Worked like charm in my case.

    0 讨论(0)
  • 2020-12-07 14:00

    Simple solution if building with maven: just place an application.properties file under src/test/resources and edit as appropriate for testing.

    The Spring (Boot) Profile mechanism is a pretty powerful tool that, in scope, goes way beyond "swapping settings between test time and run time". Although, clearly, as demonstrated, it can do that also :)

    0 讨论(0)
  • 2020-12-07 14:06

    @Sanjay has one way to put it but I find it confusing. You could just as well have only a production profile that you enable when you're in production, something like:

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

    And don't specify anything else. If you add an embedded database in test scope, it will be available in your tests. If you run your tests with the default profile (no customization whatsoever), it won't find any database information (since these are stored in the production profile). In that case, it will try to find an embedded database and start it for you. If you need more customization for some reason, you can have a application-test.properties for those (you'll need to add ActiveProfiles("test") to your test(s).

    0 讨论(0)
  • 2020-12-07 14:08

    Another approach is to add the annotation @AutoConfigureTestDatabase to you test class. My tests usually look like this:

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

    Note that the embedded database dependency needs to be added in the pom.xml file. For embedded database this annotation is not necessary it will work even if only the dependency is added in pom file.

    0 讨论(0)
  • 2020-12-07 14:13

    Spring profiles can be used for this. This would be a specific way:

    Have environment specific properties files:

    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
    

    Have both MySQL and H2 drivers in pom.xml, like this:

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

    Last but not the least, annotate Test classes with @ActiveProfiles("test").

    0 讨论(0)
  • 2020-12-07 14:15

    This solution enables common settings for develop and test. Is based on this solution: Override default Spring-Boot application.properties settings in Junit Test

    1. application.properties in 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
    
    1. test.properties (src/main/resources/application.properties) which overrides and adds properties in 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
    
    
    1. settings in pom.xml for H2 and Postgre databases
          <!-- h2 -->
          <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
          </dependency>
    
        <!-- postgress -->
          <dependency>
             <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>
          </dependency>
    
    
    1. In test class:
        @RunWith(SpringRunner.class)
        @SpringBootTest
        @TestPropertySource(locations = "classpath:test.properties")
        public class ModelTest { 
    
        }
    
    0 讨论(0)
提交回复
热议问题