10

I have a spring boot application, it has a couple of @Entity classes and @RepositoryRestResource repositort interfaces for them. Now I want to write some tests, where I can check that I can add a new record into my database using those repositories, but I don't want to use my configured MySQL database for it, but instead I want to use some embedded db like H2. At the moment I have an application.properties file, which looks like this:

spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=qwerty123

Question: How do I configure my app to use other db for tests? I have no xml in my project, everything is based on annotations. I tried to define @Configuration class with @Bean to create DataSource and then use it with @ContextConfiguration annotation on test class, but it says that it can't load context.

3 Answers 3

17

If you are using a Maven project, you can add a application.properties file into your src/test/resources, for example with the following content.

# Create DDL
spring.jpa.hibernate.ddl-auto=create

# H2 in local file system allowing other simultaneous connections
spring.datasource.url=jdbc:h2:~/test;AUTO_SERVER=TRUE

Also, you need to include H2 as dependency (pom.xml):

<dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
   <version>1.4.193</version>
</dependency>
Sign up to request clarification or add additional context in comments.

2 Comments

It still uses MySQL db instead if I do it that way. Should I provide any more info on test class? Some annotations to explicitly define these properties and not those from main folder?
ok, I added @PropertySource("path/to/properties") annotation for test class and now it works, thanks
13

Spring Boot provides 2 magic annotations related to JPA autoconfigs for tests: @DataJpaTest and @AutoConfigureTestDatabase. The javadoc says:

By default, tests annotated with @DataJpaTest will use an embedded in-memory database (replacing any explicit or usually auto-configured DataSource). The @AutoConfigureTestDatabase annotation can be used to override these settings.

If you are looking to load your full application configuration, but use an embedded database, you should consider @SpringBootTest combined with @AutoConfigureTestDatabase rather than this annotation.

So, the only thing you absolutely need is a dependency in your pom file:

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>

That's it. However, spring boot spec also has 2 useful caveats:

You need not provide any connection URLs. You need only include a build dependency to the embedded database that you want to use. If you are using this feature in your tests, you may notice that the same database is reused by your whole test suite regardless of the number of application contexts that you use. If you want to make sure that each context has a separate embedded database, you should set spring.datasource.generate-unique-name to true.

And another one:

If, for whatever reason, you do configure the connection URL for an embedded database, take care to ensure that the database’s automatic shutdown is disabled. If you use H2, you should use DB_CLOSE_ON_EXIT=FALSE to do so. If you use HSQLDB, you should ensure that shutdown=true is not used. Disabling the database’s automatic shutdown lets Spring Boot control when the database is closed, thereby ensuring that it happens once access to the database is no longer needed.

That's almost all you need to know about Spring Boot and embedded DBs. I see absolutely no reason to use the scope of dependency other than test, unless you actually intentionally configure an embedded DB for your application runtime. Believe it or not H2 jar alone takes 1.8M inside your fat jar. In the world on granular microservices, serverless and lambda functions it does matter what you put inside your apps.

I would also recommend checking the options in @AutoConfigureTestDatabase. I use it with @SpringBootTest, but it can also be used with some other annotations, namely @DataJpaTest, both mentioned above: enter image description here

Comments

2

You will need to use Spring Profiles - https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-set-active-spring-profiles

You will define an active profile using "spring.profiles.active = development" and then including H2 in your development profile.

The examples use YAML, but they work in standard properties files as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.