How to solve IllegalStateException Unable to find @SpringBootConfiguration exception
1. The exception
When we test springboot application , sometimes we got IllegalStateException: unable to find @SpringBootConfiguration exception,like this:
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
at org.springframework.util.Assert.state(Assert.java:392)
at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.getOrFindConfigurationClasses(SpringBootTestContextBootstrapper.java:173)
at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.processMergedContextConfiguration(SpringBootTestContextBootstrapper.java:133)
at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(
....
Process finished with exit code 255
2. The project layout
At first , the project layout is as follows:
my-test-project
+--pom.xml
+--src
+--main
+--com
+--example1
+--Application.java
+--test
+--com
+--example2
+--TestAsync.java
The Application.java code is:
package com.example1; //notice this package
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The test code is:
package com.example2; //notice this package name
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestAsync {
...
}
eg.
- The @SpringBootApplication is Application.java, this class has a package named com.example1
- The test class’ package is com.example2,which is not the same as the @SpringBootApplication package name nor is the subpackage of it.
This picture shows the package difference.
3. The reason of this Unable to find @SpringBootConfiguration exception
The real reason of the Unable to find @SpringBootConfiguration exception is the test class can not find the @SpringBootApplication.
But why is that happened? I do have a @SpringBootApplication class, why the test class can not see it?
Because the @SpringBootTest class has a specific mechanism of finding the @SpringBootApplication , as the following picture shows:
As the picture shows, the @SpringBootTest class would find the @SpringBootApplication from its package com.example2 to com and to /, if still not found, it would throw the Unable to find @SpringBootConfiguration exception.
This is the official description of this mechanism:
The search algorithm works up from the package that contains the test until it finds a @SpringBootApplication or @SpringBootConfiguration annotated class. As long as you’ve structure your code in a sensible way your main configuration is usually found.
3. How to solve this problem
There are three ways to solve this problem/Exception:
- Move your test class to com.example1 package, which is the same as the @SpringBootAplication class
- Move your test class to a subpackage of com.example1, for example, com.example1.test
- Use @SpringBootTest(classes = Application.class),where the Application.class is the @SpringBootApplication class
3.1 Way 1 demo
3.2 way2 demo
3.3 The 3rd way
Change the @SpringBootTest class as follows:
package com.example2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.example1.Application;//notice this line
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class) //notice this line
public class TestAsync {
...
}
As the comment says, you should notice that there are two difference with the original version:
- We import the com.example1.Application
- We add params to @SpringBootTest annotation to specify the @SpringBootApplication class
This means you need not to find it, just use it.
Now run test again, the exception disappeared.
You can find detail documents about the springboot here: