5

I am developing a micro-service application using Spring Boot. My application will use for production configuration a Postgres DB and for Spring Boot auto-test a H2 DB. My pom.xml includes therefore both dependencies (H2 + Postgres). I tried to associate H2 dependency with tes scope, and Postgres with runtime as following:

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

I can see when running mvn test that Spring Boot selects by default postgres database which is not present within my unit test environment. This is the reason why I prefer using H2 for running unit tests.

Is there a proper way to tell spring boot to use H2 for test and Postgres otherwise?

I don't know if using different application.properties file (one in src/main/resources and the other in src/test/resources) would solve the issue.

3
  • You have your scopes backwards. Commented Jun 4, 2019 at 10:59
  • Oh yeah right! I'll invert and check. Thanks! Commented Jun 4, 2019 at 11:10
  • @chrylis inverting runtime/scope didn't resolve the issue. As explained by g00glen00b, a runtime scope dependency will also be available in test scope. There will still be a conflict between H2 and Postgres Commented Jun 4, 2019 at 11:38

1 Answer 1

5

You should be aware that there are multiple class paths, such as:

  1. The compile-time classpath,
  2. The runtime classpath,
  3. The testing classpath.

When you use <scope>runtime</scope>, the dependency will be available in both the runtime classpath as the testing classpath, as mentioned by the documentation:

This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.

That means that even when you're executing your tests, Postgres would still be on your classpath if you use <scope>runtime</scope>.


The solution you mentioned, by providing two separate application.properties is the right choice.

Within src/main/resources/application.properties, you could configure the datasource like this:

spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase

Within src/test/resources/application.properties, you could configure the datasource like this:

spring.datasource.url=jdbc:h2:mydatabase

If you need more fine-grained control, you can use Spring profiles. For example, you could use a profile called "testdb", and then annotate your test using @ActiveProfiles("testdb").

Now you could create a file called application-testdb.properties and add the properties you need to set up your test database.

Sign up to request clarification or add additional context in comments.

5 Comments

@HichemBOUSSETTA Note that it's generally preferably to use profiles rather than relying on overlaying filenames, and it's especially preferable not to include credentials in your source code at all--use environment variables at runtime.
Yes I already do thanks! Actually, here I wanted to minimize the configuration for the ci pipeline. I am looking preferably for a way to just run mvn test without any additional configuration or secrets
@g00glen00b the solution with 2 application.properties, one for test and another one for packaging works perfectly. Thanks!
If we have both dependencies in pom, and then have 2 separate application.properties, then this clash won't happen?
@Mandroid yes, if you have both dependencies present, then you need to tell spring which driver it has to use; you can use the spring variable spring.datasource.driver-class-name=xxx to use one driver or another according to your needs

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.