Nie można znaleźć @SpringBootConfiguration podczas wykonywania JpaTest

185

Jestem nowy w frameworkach (właśnie zdałem klasę) i po raz pierwszy korzystam z Spring Boot.

Próbuję uruchomić prosty test Junita, aby sprawdzić, czy moje CrudRepositories rzeczywiście działają.

Błąd, który ciągle się pojawia to:

Nie można znaleźć @SpringBootConfiguration, musisz użyć @ContextConfiguration lub @SpringBootTest (klas = ...) z testem java.lang.IllegalStateException

Czy Spring Boot się nie konfiguruje?

Moja klasa testowa:

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

 }

Starter aplikacji My Spring Boot:

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

        }
    }

Moje repozytorium:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}
Thomas Billet
źródło

Odpowiedzi:

264

Rzeczywiście, Spring Boot w większości się ustawia. Prawdopodobnie możesz już pozbyć się dużo kodu, który opublikowałeś, szczególnie w Application.

Chciałbym, abyś zawarł nazwy wszystkich swoich klas, a przynajmniej tych dla Applicationi JpaTest. Rzeczą @DataJpaTesti kilkoma innymi adnotacjami jest to, że szukają @SpringBootConfigurationadnotacji w bieżącym pakiecie, a jeśli nie mogą jej tam znaleźć, przeglądają hierarchię pakietów, dopóki jej nie znajdą.

Na przykład, jeśli pełna nazwa twojej klasy testowej to com.example.test.JpaTesti nazwa Twojej aplikacji com.example.Application, to klasa testowa będzie w stanie znaleźć @SpringBootApplication(i tam @SpringBootConfiguration).

Jeśli aplikacja przebywał w innej gałęzi hierarchii pakietu, jednak jak com.example.application.Applicationto będzie nie go znaleźć.

Przykład

Rozważ następujący projekt Maven:

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

A następnie następująca treść w Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Następnie treści JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Wszystko powinno działać. Jeśli utworzysz nowy folder o src/main/com/examplenazwie app, a następnie umieścisz Application.javaw nim swój folder (i zaktualizujesz packagedeklarację w pliku), uruchomienie testu spowoduje następujący błąd:

java.lang.IllegalStateException: Nie można znaleźć @SpringBootConfiguration, musisz użyć @ContextConfiguration lub @SpringBootTest (klas = ...) z testem

Thomas Kåsene
źródło
1
Pozdrowienia, dziękuję za zaoferowanie rozwiązania Korzystam z konfiguracji pakietu Maven, z innym pakietem do testów i kodem aplikacji. Jeśli dobrze interpretuję to, co mówisz, że muszę skierować mój pakiet testowy do klasy aplikacji? a potem znajdzie konfigurację SpringConfiguration?
Thomas Billet
Jeśli przez „pakiet maven” masz na myśli „moduł”, to tak, moduł, w którym twoja klasa testowa musi zależeć od modułu, który Applicationjest w środku. Jeśli jednak masz na myśli src/maini src/test, to te foldery nie są częścią pakietu hierarchia. Być może lepiej jest po prostu zaktualizować swoje pytanie za pomocą zrzutu ekranu lub wyjaśnienia, jaka jest struktura projektu.
Thomas Kåsene
Właśnie rozwiązałem problem, jak powiedziałeś. po pewnym googlowaniu znalazłem sugerowaną strukturę pakietów wiosennych i zrefakturowałem je wszystkie. Teraz testy przebiegają zgodnie z oczekiwaniami. Bardzo dziękuję
Thomas Billet
Dobrze, dobrze wiedzieć! W każdym razie zaktualizowałem odpowiedź dokładniejszym przykładem.
Thomas Kåsene
3
+ - test + - com + - przykład + - JpaTest.java również działa
674158
105

Konfiguracja jest dołączona do klasy aplikacji, więc następujące ustawienia skonfigurują wszystko poprawnie:

@SpringBootTest(classes = Application.class)

Przykład z projektu JHipster tutaj .

mrts
źródło
To wydaje się być idealnym rozwiązaniem. Nie muszę przenosić żadnej klasy ani folderu.
Abhishek Aggarwal
21

Warto sprawdzić, czy dokonano refaktoryzacji nazwy pakietu głównej klasy z adnotacjami @SpringBootApplication. W takim przypadku zestaw testowy powinien znajdować się w odpowiednim pakiecie, w przeciwnym razie będzie go szukał w starszym pakiecie. tak było w moim przypadku.

Mohammed Rafeeq
źródło
11

Oprócz tego, co powiedział Thomas Kåsene, możesz również dodać

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

do adnotacji testowej, aby określić, gdzie powinna szukać drugiej klasy, jeśli nie chcesz refaktoryzować hierarchii plików. Oto, na co wskazuje komunikat o błędzie, mówiąc:

Unable to find a @SpringBootConfiguration, you need to use 
@ContextConfiguration or @SpringBootTest(classes=...) ...
Cameron Gagnon
źródło
To bardzo cenna odpowiedź! Dziękuję @ameramer!
Lance Kind
6

W moim przypadku pakiety różniły się między klasami Application i Test

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

i

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

Po ich uzgodnieniu testy przebiegły poprawnie.

Nacięcie
źródło
5

To działa dla mnie

nazwa pakietu powyższej klasy testowej jest zmieniana na taką samą jak nazwa pakietu normalnej klasy.

zmień na to

powiesić Gao
źródło
3

Plaster badanie przewidziane w Boot 1,4 Wiosna przyniosła m.in. zorientowanych możliwości testowych.

Na przykład,

@JsonTest zapewnia proste środowisko Jacksona do testowania serializacji i deserializacji json.

@WebMvcTest zapewnia fałszywe środowisko sieciowe, może określić klasę kontrolera do testu i wstrzyknąć MockMvc do testu.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest przygotuje osadzoną bazę danych i zapewni podstawowe środowisko JPA na potrzeby testu.

@RestClientTest zapewnia środowisko testowe klienta REST, szczególnie RestTemplateBuilder itp.

Te adnotacje nie składają się z SpringBootTest, są połączone w szereg AutoconfigureXXX, a A @TypeExcludesFilteradnotacje.

Spójrz na @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 {}

Możesz dodać adnotację @AutoconfigureXXX, aby zastąpić domyślną konfigurację.

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

Spójrzmy na twój problem,

  1. Nie mieszaj @DataJpaTesti @SpringBootTest, jak wspomniano powyżej @DataJpaTest, zbuduje konfigurację na swój własny sposób (np. Domyślnie zamiast tego spróbuje przygotować osadzoną H2) z dziedziczenia konfiguracji aplikacji. @DataJpaTestjest przeznaczony do wycinka testowego .
  2. Jeśli chcesz dostosować konfigurację @DataJpaTest, przeczytaj ten oficjalny wpis blogu z Spring.io na ten temat (trochę nudny).
  3. Podzielić w konfiguracji Applicationdo mniejszych konfiguracjach według funkcji, takich jak WebConfig, DataJpaConfigitp pełna konfiguracja funkcjonalnym (mieszane internetowej, danych, bezpieczeństwo itp) spowodował również swoje slice testy testy oparte być nie powiodło się. Sprawdź próbki testowe w mojej próbce .
Hantsy
źródło
1

Myślę, że najlepszym rozwiązaniem tego problemu jest wyrównanie struktury folderów testów ze strukturą folderów aplikacji.

Miałem ten sam problem, który został spowodowany przez powielenie mojego projektu z innego projektu struktury folderów.

jeśli twój projekt testowy i projekt aplikacji będą miały tę samą strukturę, nie będziesz musiał dodawać żadnych specjalnych adnotacji do swoich klas testowych i wszystko będzie działać tak, jak jest.

srebro
źródło
Miałem ten sam błąd i w końcu zorientowałem się, że nazwa pakietu dla klasy testowej zawiera literówkę „reguła” zamiast „reguł”. Po naprawieniu nazwy pakietu błąd zniknął.
Gopal Bairwa
1

Gdy wszystkie klasy były w tym samym pakiecie, działały klasy testowe. Gdy tylko przeniosłem wszystkie klasy Java do innego pakietu w celu utrzymania właściwej struktury projektu, otrzymałem ten sam błąd.

Rozwiązałem go, podając moją główną nazwę klasy w klasie testowej, jak poniżej.

@SpringBootTest(classes=JunitBasicsApplication.class)
SumataPatil
źródło
1

Miałem ten sam problem i rozwiązałem go, dodając pustą klasę z adnotacją SpringBootApplicationw pakiecie głównym folderu src / test / java

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

@SpringBootApplication
public class CoreTestConfiguration {}
Enrico Giurin
źródło
0

W moim przypadku
upewnij się, że twoje ( test packageimię ) YourApplicationTestsjest równoważne ( main packageimię ).

ahmednabil88
źródło
-2
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);
    }
}

Powyższe adnotacje działały dla mnie dobrze. Używam wiosennego rozruchu z JPA.

Umesh G.
źródło