Skip to content

Why Spring Boot Tests Ignore @EnableAutoConfiguration Exclusion Annotations

Problem

When I run my Spring Boot unit tests, I got this error:

Test error output
Cannot determine embedded database for tests.
If you want an embedded database please put a supported one on the classpath.

The strange thing is: my main application runs fine without a database, but tests fail.

Environment

  • Spring Boot 2.x
  • Java 11
  • Gradle build
  • No database dependency (intentionally)

What Happened?

I have a Spring Boot application that doesn’t need a database. I configured it to exclude database autoconfiguration:

Application.java (problematic)
@SpringBootApplication
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

When I start the application, it works. No database errors.

But when I run my test:

MyTest.java
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyTest {
@Test
public void testEndpoint() {
// test logic
}
}

I get the “Cannot determine embedded database” error.

How to Solve It?

I tried different approaches.

First attempt: I thought the exclusion wasn’t being read. So I added exclusions directly in the test:

MyTest.java (attempt 1)
@SpringBootTest(
classes = Application.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@TestPropertySource(properties = {
"spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"
})
public class MyTest { ... }

This worked, but it’s messy. I have to duplicate exclusions in every test.

Second attempt: I looked at the annotation hierarchy more carefully.

@SpringBootApplication is actually a composite annotation that combines:

  • @Configuration
  • @EnableAutoConfiguration
  • @ComponentScan

When I use a separate @EnableAutoConfiguration(exclude = ...), the test framework processes the Application class differently. It doesn’t inherit that exclusion properly.

The real solution: Use the exclude property directly on @SpringBootApplication:

Application.java (correct)
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

Now my tests work without any database configuration.

The Reason

The key reason is how @SpringBootTest processes the Application class.

When you use @SpringBootTest(classes = Application.class), it loads the Application class and creates a test context. But the test context creation doesn’t fully honor a separate @EnableAutoConfiguration annotation placed next to @SpringBootApplication.

The @SpringBootApplication(exclude = ...) property is part of the composite annotation. The test framework explicitly recognizes this exclude property and applies it to the test context.

This is a subtle but important distinction in Spring Boot’s annotation processing.

Why include JpaRepositoriesAutoConfiguration?

When excluding database autoconfiguration, you should also exclude JpaRepositoriesAutoConfiguration.class. This prevents Spring from trying to set up JPA repository scanning, which also requires a datasource.

Alternative: Remove JPA starter entirely

If your application truly never needs a database, the cleaner solution is to remove spring-boot-starter-data-jpa from your dependencies:

build.gradle
dependencies {
// Remove this if you don't need database:
// implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

This prevents autoconfiguration attempts at the root. No exclusions needed.

Summary

In this post, I showed why Spring Boot tests ignore @EnableAutoConfiguration(exclude) annotations. The key point is to use @SpringBootApplication(exclude = ...) instead, because the test framework properly recognizes the exclude property on the composite annotation.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments