Unable to find a @SpringBootConfiguration when doing a JpaTest

Thomas Billet picture Thomas Billet · Aug 22, 2016 · Viewed 192.7k times · Source

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);

    }
}

Answer

Thomas K&#229;sene picture Thomas Kåsene · Aug 22, 2016

Indeed, Spring Boot does set itself up for the most part. You can probably already get rid of a lot of the code you posted, especially in Application.

I wish you had included the package names of all your classes, or at least the ones for Application and JpaTest. The thing about @DataJpaTest and a few other annotations is that they look for a @SpringBootConfiguration annotation in the current package, and if they cannot find it there, they traverse the package hierarchy until they find it.

For example, if the fully qualified name for your test class was com.example.test.JpaTest and the one for your application was com.example.Application, then your test class would be able to find the @SpringBootApplication (and therein, the @SpringBootConfiguration).

If the application resided in a different branch of the package hierarchy, however, like com.example.application.Application, it would not find it.

Example

Consider the following Maven project:

my-test-project
  +--pom.xml
  +--src
    +--main
      +--com
        +--example
          +--Application.java
    +--test
      +--com
        +--example
          +--test
            +--JpaTest.java

And then the following content in Application.java:

package com.example;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Followed by the contents of JpaTest.java:

package com.example.test;

@RunWith(SpringRunner.class)
@DataJpaTest
public class JpaTest {

    @Test
    public void testDummy() {
    }
}

Everything should be working. If you create a new folder inside src/main/com/example called app, and then put your Application.java inside it (and update the package declaration inside the file), running the test will give you the following error:

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