[java] Unable to find a @SpringBootConfiguration when doing a JpaTest

I'm new to frameworks (just passed the class) and this is my first time using Spring Boot.

I'm trying to run a simple Junit test to see if my CrudRepositories are indeed working.

The error I keep getting is:

Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test java.lang.IllegalStateException

Doesn't Spring Boot configure itself?

My Test Class:

@RunWith(SpringRunner.class)
@DataJpaTest
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class JpaTest {

@Autowired
private AccountRepository repository;

@After
public void clearDb(){
    repository.deleteAll();
}

 @Test
 public void createAccount(){
     long id = 12;
     Account u = new Account(id,"Tim Viz");
     repository.save(u);

     assertEquals(repository.findOne(id),u);

 }


 @Test
 public void findAccountByUsername(){
     long id = 12;
     String username = "Tim Viz";
     Account u = new Account(id,username);
     repository.save(u);

     assertEquals(repository.findByUsername(username),u);

 }

My Spring Boot application starter:

@SpringBootApplication
@EnableJpaRepositories(basePackages = {"domain.repositories"})
@ComponentScan(basePackages = {"controllers","domain"})
@EnableWebMvc
@PropertySources(value    {@PropertySource("classpath:application.properties")})
    @EntityScan(basePackages={"domain"})
    public class Application extends SpringBootServletInitializer {
        public static void main(String[] args) {
            ApplicationContext ctx = SpringApplication.run(Application.class, args);         

        }
    }

My Repository:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}

This question is related to java spring junit spring-boot spring-data

The answer is


I had the same issue and I solved by adding an empty class annotated with SpringBootApplication in the root package of the folder src/test/java

package org.enricogiurin.core;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoreTestConfiguration {}

It is worth to check if you have refactored package name of your main class annotated with @SpringBootApplication. In that case the testcase should be in an appropriate package otherwise it will be looking for it in the older package . this was the case for me.


I think that the best solution for this issue is to align your tests folders structure with the application folder structure.

I had the same issue which was caused by duplicating my project from a different folder structure project.

if your test project and your application project will have the same structure you will not be required to add any special annotations to your tests classes and everything will work as is.


In my case the packages were different between the Application and Test classes

package com.example.abc;
...
@SpringBootApplication
public class ProducerApplication {

and

package com.example.abc_etc;
...
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerApplicationTest {

After making them agree the tests ran correctly.


import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;



@RunWith(SpringRunner.class)
@DataJpaTest
@SpringBootTest
@AutoConfigureWebMvc
public class RepoTest {

    @Autowired
    private ThingShiftDetailsRepository thingShiftDetailsRepo;

    @Test
    public void findThingShiftDetails() {
            ShiftDetails details = new ShiftDetails();
            details.setThingId(1);

            thingShiftDetailsRepo.save(details);

            ShiftDetails dbDetails = thingShiftDetailsRepo.findByThingId(1);
            System.out.println(dbDetails);
    }
}

Above annotations worked well for me. I am using spring boot with JPA.


In addition to what Thomas Kåsene said, you can also add

@SpringBootTest(classes=com.package.path.class)

to the test annotation to specify where it should look for the other class if you didn't want to refactor your file hierarchy. This is what the error message hints at by saying:

Unable to find a @SpringBootConfiguration, you need to use 
@ContextConfiguration or @SpringBootTest(classes=...) ...

Make sure the test class is in a sub-package of your main spring boot class


When all the classes were in same package, test classes were working. As soon as I moved all the java classes to different package to maintain proper project structure I was getting the same error.

I solved it by providing my main class name in the test class like below.

@SpringBootTest(classes=JunitBasicsApplication.class)

Configuration is attached to the application class, so the following will set up everything correctly:

@SpringBootTest(classes = Application.class)

Example from the JHipster project here.


In my case
Make sure your (test package name) of YourApplicationTests is equivalent to the (main package name).


It work fo me

the package name of the above test class is changed to the same as the package name of the normal class.

change to this


This is more the the error itself, not answering the original question:

We were migrating from java 8 to java 11. Application compiled successfully, but the errors Unable to find a @SpringBootConfiguration started to appear in the integration tests when ran from command line using maven (from IntelliJ it worked).

It appeared that maven-failsafe-plugin stopped seeing the classes on classpath, we fixed that by telling failsafe plugin to include the classes manually:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <configuration>
                <additionalClasspathElements>
                    <additionalClasspathElement>${basedir}/target/classes</additionalClasspathElement>
                </additionalClasspathElements>
            </configuration>
            ...
        </plugin>

The test slice provided in Spring Boot 1.4 brought feature oriented test capabilities.

For example,

@JsonTest provides a simple Jackson environment to test the json serialization and deserialization.

@WebMvcTest provides a mock web environment, it can specify the controller class for test and inject the MockMvc in the test.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest will prepare an embedded database and provides basic JPA environment for the test.

@RestClientTest provides REST client environment for the test, esp the RestTemplateBuilder etc.

These annotations are not composed with SpringBootTest, they are combined with a series of AutoconfigureXXX and a @TypeExcludesFilter annotations.

Have a look at @DataJpaTest.

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(SpringBootTestContextBootstrapper.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJpaTypeExcludeFilter.class)
@Transactional
@AutoConfigureCache
@AutoConfigureDataJpa
@AutoConfigureTestDatabase
@AutoConfigureTestEntityManager
@ImportAutoConfiguration
public @interface DataJpaTest {}

You can add your @AutoconfigureXXX annotation to override the default config.

@AutoConfigureTestDatabase(replace=NONE)
@DataJpaTest
public class TestClass{
}

Let's have a look at your problem,

  1. Do not mix @DataJpaTest and @SpringBootTest, as said above @DataJpaTest will build the configuration in its own way(eg. by default, it will try to prepare an embedded H2 instead) from the application configuration inheritance. @DataJpaTest is designated for test slice.
  2. If you want to customize the configuration of @DataJpaTest, please read this official blog entry from Spring.io for this topic,(a little tedious).
  3. Split the configurations in Application into smaller configurations by features, such as WebConfig, DataJpaConfig etc. A full featured configuration(mixed web, data, security etc) also caused your test slice based tests to be failed. Check the test samples in my sample.

In my case I was using the Test class from wrong package. when I replaced import org.junit.Test; with import org.junit.jupiter.api.Test; it worked.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to spring

Are all Spring Framework Java Configuration injection examples buggy? Two Page Login with Spring Security 3.2.x Access blocked by CORS policy: Response to preflight request doesn't pass access control check Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified Spring Data JPA findOne() change to Optional how to use this? After Spring Boot 2.0 migration: jdbcUrl is required with driverClassName The type WebMvcConfigurerAdapter is deprecated No converter found capable of converting from type to type

Examples related to junit

Eclipse No tests found using JUnit 5 caused by NoClassDefFoundError for LauncherFactory How to resolve Unneccessary Stubbing exception JUnit 5: How to assert an exception is thrown? How do I mock a REST template exchange? Class Not Found: Empty Test Suite in IntelliJ Unable to find a @SpringBootConfiguration when doing a JpaTest Failed to load ApplicationContext (with annotation) Example of Mockito's argumentCaptor Mockito - NullpointerException when stubbing Method Spring jUnit Testing properties file

Examples related to spring-boot

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Why am I getting Unknown error in line 1 of pom.xml? Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured How to resolve Unable to load authentication plugin 'caching_sha2_password' issue ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified After Spring Boot 2.0 migration: jdbcUrl is required with driverClassName ERROR Source option 1.5 is no longer supported. Use 1.6 or later How to start up spring-boot application via command line? JSON parse error: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value

Examples related to spring-data

Call another rest api from my server in Spring-Boot Consider defining a bean of type 'service' in your configuration [Spring boot] How to beautifully update a JPA entity in Spring Data? Unable to find a @SpringBootConfiguration when doing a JpaTest Spring Data and Native Query with pagination Spring Boot - Loading Initial Data Disable all Database related auto configuration in Spring Boot crudrepository findBy method signature with multiple in operators? What is this spring.jpa.open-in-view=true property in Spring Boot? Spring Data JPA and Exists query