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

86,124

Solution 1

When the Spring Boot starts, it scans the classpath from the top to the bottom of the project to find the config file. Your config is under another files and that is a reason of the problem. Move you config upper to the monolith package and everything gonna be fine.

Solution 2

src/test/java packages and src/main/java packages should match. I had same issue where

  • my src/main/java packages were starting with com.comp.example but
  • src/test/java packages were starting with com.sample.example

Because of this spring boot application was not able to pickup the configuration of the application, which it picks up from @SpringBootApplication class. So test case should fall under the same packages where @SpringBootApplication in src/main/java is written.

Solution 3

@SpringBootTest has a parameter named classes. It accepts an array of classes for configuration. Add the class for the config file to it, for example:

@SpringBootTest(classes={com.lapots.game.monolith.web.GrandJourneyMonolithApplication.class})

Solution 4

The Test src/test/java files should also follow the same directory structure as in src/main/java.

enter image description here

Solution 5

In my case this was due to some [move|copy/paste] of classes. For some, the package clause was either [not updated correctly|not present] and the changes were not picked up but the IDE.

Anyways, review your project packaging.

Share:
86,124

Related videos on Youtube

lapots
Author by

lapots

Interest driven developer. JVM platform enthusiast. Run towards full stack DevOps!

Updated on July 05, 2022

Comments

  • lapots
    lapots almost 2 years

    I am using Spring Data JPA and Spring Boot. The layout of the application is this

    main
        +-- java
            +-- com/lapots/game/monolith
                +-- repository/relational
                    +--RelationalPlayerRepository.java
                +-- web
                    +--GrandJourneyMonolithApplication.java
                    +-- config
                        +-- RelationalDBConfiguration.java
    test
        +-- java
            +-- com/lapots/game/monolith
                +-- repository/relational
                    +-- RelationalPlayerRepositoryTests.java
                +-- web
                    +-- GrandJourneyMonolithApplicationTests.java
    

    The repository for my object looks like this

    public interface RelationalPlayerRepository extends JpaRepository<Player, Long> {
    }
    

    Additionally for the repositories I provided a configuration

    @Configuration
    @EnableJpaRepositories(basePackages = "com.lapots.game.monolith.repository.relational")
    @EntityScan("com.lapots.game.monolith.domain")
    public class RelationalDBConfiguration {
    }
    

    My main application looks like this

    @SpringBootApplication
    @ComponentScan("com.lapots.game.monolith")
    public class GrandJourneyMonolithApplication {
    
        @Autowired
        private RelationalPlayerRepository relationalPlayerRepository;
    
        public static void main(String[] args) {
            SpringApplication.run(GrandJourneyMonolithApplication.class, args);
        }
    
        @Bean
        public CommandLineRunner initPlayers() {
            return (args) -> {
                Player p = new Player();
                p.setLevel(10);
                p.setName("Master1909");
                p.setClazz("warrior");
    
                relationalPlayerRepository.save(p);
            };
        }
    }
    

    Test for application looks like this

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class GrandJourneyMonolithApplicationTests {
    
        @Test
        public void contextLoads() {
        }
    
    }
    

    The test for repository looks like this

    @RunWith(SpringRunner.class)
    @DataJpaTest
    public class RelationalPlayerRepositoryTests {
    
        @Autowired
        private TestEntityManager entityManager;
    
        @Autowired
        private RelationalPlayerRepository repository;
    
        @Test
        public void testBasic() {
            Player expected = createPlayer("Master12", "warrior", 10);
            this.entityManager.persist(expected);
            List<Player> players = repository.findAll();
            assertThat(repository.findAll()).isNotEmpty();
            assertEquals(expected, players.get(0));
        }
    
        private Player createPlayer(String name, String clazz, int level) {
            Player p = new Player();
            p.setId(1L);
            p.setName(name);
            p.setClazz(clazz);
            p.setLevel(level);
            return p;
        }
    }
    

    But when I try to run the tests I get the error

    Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.041 sec <<< FAILURE! - in com.lapots.game.monolith.repository.relational.RelationalPlayerRepositoryTests
    initializationError(com.lapots.game.monolith.repository.relational.RelationalPlayerRepositoryTests)  Time elapsed: 0.006 sec  <<< ERROR!
    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:70)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.getOrFindConfigurationClasses(SpringBootTestContextBootstrapper.java:202)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.processMergedContextConfiguration(SpringBootTestContextBootstrapper.java:137)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:409)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildDefaultMergedContextConfiguration(AbstractTestContextBootstrapper.java:323)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildMergedContextConfiguration(AbstractTestContextBootstrapper.java:277)
    at org.springframework.test.context.support.AbstractTestContextBootstrapper.buildTestContext(AbstractTestContextBootstrapper.java:112)
    at org.springframework.boot.test.context.SpringBootTestContextBootstrapper.buildTestContext(SpringBootTestContextBootstrapper.java:82)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:120)
    at org.springframework.test.context.TestContextManager.<init>(TestContextManager.java:105)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTestContextManager(SpringJUnit4ClassRunner.java:152)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:143)
    at org.springframework.test.context.junit4.SpringRunner.<init>(SpringRunner.java:49)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
    

    What is the problem? Domain Player loooks like this

    @Data
    @Entity
    @Table(schema = "app", name = "players")
    public class Player {
        @Id
        @GeneratedValue
        private Long id;
    
        @Transient
        Set<Player> comrades;
    
        @Column(unique = true)
        private String name;
    
        private int level;
    
        @Column(name = "class")
        private String clazz;
    }
    
    • Sam Brannen
      Sam Brannen over 6 years
      What happens if you annotate RelationalPlayerRepositoryTests with @ContextConfiguration(classes = GrandJourneyMonolithApplication.class)?
    • lapots
      lapots over 6 years
      @SamBrannen it shows error that it failed to replace DataSource with embedded
  • lapots
    lapots over 6 years
    but shouldn't it possible to specify the configuration class in the test?
  • lapots
    lapots over 6 years
    also I moved configuration class and it didn't help
  • Phil Webb
    Phil Webb over 6 years
    The answer above should be correct. Structure your application as suggested in the documentation and the test should be able to search up to find the configuration. You might be having additional problems due to annotations that are disabling auto-configuration. Try also removing @EnableJpaRepositories, @EntityScan and @ComponentScan.
  • Sasha Bond
    Sasha Bond about 3 years
    this worked for me: @SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.DEFINED_PORT) - see stackoverflow.com/questions/43468754/…
  • VC2019
    VC2019 about 3 years
    I am using Spring Boot with a simple REST controller. Not using any JPA and was getting same error as specified in the title here for my controller test. Also I am using a custom configuration for my Spring boot app. This answer (Oct 19 '18 at 7:20 Saurabh Parmar) helped. The root cause for me too was the package name. The package for my test under the src/test/java was not matching the one under the src/main/java. Once I fixed that it worked.
  • Heiner
    Heiner about 3 years
    I had a typo in my test package name
  • Renato Gama
    Renato Gama almost 3 years
    I completely forgot to add the package name. That did the trick
  • Emiliano Schiano
    Emiliano Schiano over 2 years
    To avoid the need of matching the test classes packages with production code ones, just specify in the SpringBootTest annotation the class to be used to load the app context like this @SpringBootTest(classes = Application.class)