Impossibile trovare una @SpringBootConfiguration quando si esegue un JpaTest


186

Sono nuovo ai framework (appena passato il corso) e questa è la prima volta che utilizzo Spring Boot.

Sto cercando di eseguire un semplice test Junit per vedere se i miei CrudRepositories funzionano davvero.

L'errore che continuo a ricevere è:

Impossibile trovare @SpringBootConfiguration, è necessario utilizzare @ContextConfiguration o @SpringBootTest (classi = ...) con il test java.lang.IllegalStateException

Spring Boot non si configura da solo?

La mia classe di test:

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

 }

Il mio avviatore dell'applicazione 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);         

        }
    }

Il mio repository:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}

Risposte:


264

In effetti, Spring Boot si è impostato per la maggior parte. Probabilmente puoi già sbarazzarti di molto del codice che hai pubblicato, specialmente in Application.

Vorrei che tu avessi incluso i nomi dei pacchetti di tutte le tue classi, o almeno quelli per Applicatione JpaTest. Il punto @DataJpaTeste alcune altre annotazioni è che cercano @SpringBootConfigurationun'annotazione nel pacchetto corrente e, se non riescono a trovarla lì, attraversano la gerarchia del pacchetto fino a quando non la trovano.

Ad esempio, se il nome completo per la tua classe di test era com.example.test.JpaTeste quello per la tua applicazione com.example.Application, la tua classe di test sarebbe in grado di trovare il @SpringBootApplication(e in esso, il @SpringBootConfiguration).

Se l'applicazione risiedesse in un diverso ramo della gerarchia dei pacchetti, tuttavia, come com.example.application.Application, non la troverebbe.

Esempio

Considera il seguente progetto Maven:

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

E poi il seguente contenuto in Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Seguito dal contenuto di JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Tutto dovrebbe funzionare. Se crei una nuova cartella src/main/com/examplechiamata al suo interno appe poi la inserisci al suo Application.javainterno (e aggiorni la packagedichiarazione all'interno del file), l'esecuzione del test ti darà il seguente errore:

java.lang.IllegalStateException: impossibile trovare una @SpringBootConfiguration, è necessario utilizzare @ContextConfiguration o @SpringBootTest (classi = ...) con il test


1
Saluti, grazie per aver offerto una soluzione Sto usando l'installazione del pacchetto Maven, con un pacchetto diverso per i test e il codice dell'applicazione. Se interpreto bene ciò che stai dicendo è che devo indirizzare il mio pacchetto di test alla classe Application? e poi troverà SpringConfiguration?
Thomas Billet,

Se per "pacchetto Maven" intendi "modulo", allora sì, il modulo in cui si trova la tua classe di test deve dipendere dal modulo che si Applicationtrova. Se, tuttavia, intendi src/maine src/test, allora quelle cartelle non fanno parte del pacchetto gerarchia. Forse stai meglio aggiornando la tua domanda con uno screenshot o una spiegazione di come sia la struttura del tuo progetto.
Thomas Kåsene,

Ho appena risolto il problema come hai detto. dopo aver cercato su Google ho trovato la struttura del pacchetto di molle suggerita e li ho rifattorizzati tutti. Ora i test vengono eseguiti come previsto. Grazie mille
Thomas Billet,

Va bene, buono a sapersi! Ho comunque aggiornato la risposta con un esempio più approfondito.
Thomas Kåsene,

3
+ - test + - com + - esempio + - Anche JpaTest.java funziona
user674158

106

La configurazione è collegata alla classe dell'applicazione, quindi quanto segue imposterà tutto correttamente:

@SpringBootTest(classes = Application.class)

Esempio dal progetto JHipster qui .


Questa sembra essere la soluzione perfetta. Non ho bisogno di spostare alcuna classe o cartella.
Abhishek Aggarwal,

21

Vale la pena verificare se è stato annotato il nome del pacchetto refactored della classe principale @SpringBootApplication. In tal caso il testcase dovrebbe trovarsi in un pacchetto appropriato, altrimenti lo cercherà nel pacchetto precedente. questo è stato il caso per me.


12

Oltre a ciò che ha detto Thomas Kåsene, puoi anche aggiungere

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

all'annotazione di prova per specificare dove deve cercare l'altra classe se non si desidera riformattare la gerarchia dei file. Questo è ciò che suggerisce il messaggio di errore dicendo:

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

Questa è una risposta molto preziosa! Grazie @cameron!
Lance Kind,

6

Nel mio caso i pacchetti erano diversi tra le classi Application e Test

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

e

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

Dopo averli concordati, i test sono stati eseguiti correttamente.


5

Funziona per me

il nome del pacchetto della classe di test sopra è cambiato con il nome del pacchetto della classe normale.

cambia in questo


3

La sezione di test fornita in Spring Boot 1.4 ha portato funzionalità di test orientate alle funzionalità.

Per esempio,

@JsonTest fornisce un semplice ambiente Jackson per testare la serializzazione e la deserializzazione json.

@WebMvcTest fornisce un ambiente Web fittizio , può specificare la classe controller per il test e iniettare MockMvc nel test.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest preparerà un database incorporato e fornirà un ambiente JPA di base per il test.

@RestClientTest fornisce l'ambiente client REST per il test, in particolare RestTemplateBuilder ecc.

Queste annotazioni non sono composte con SpringBootTest, sono combinate con una serie di AutoconfigureXXXe una @TypeExcludesFilterannotazioni.

Dai un'occhiata @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 {}

È possibile aggiungere l'annotazione @AutoconfigureXXX per sovrascrivere la configurazione predefinita.

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

Diamo un'occhiata al tuo problema,

  1. Non mescolare @DataJpaTeste @SpringBootTest, come detto sopra @DataJpaTest, costruirà la configurazione a modo suo (ad esempio, per impostazione predefinita, proverà invece a preparare un H2 incorporato) dall'eredità della configurazione dell'applicazione. @DataJpaTestè designato per la porzione di prova .
  2. Se si desidera personalizzare la configurazione di @DataJpaTest, leggere questo post di blog ufficiale da Spring.io per questo argomento, (un po 'noioso).
  3. Dividere le configurazioni Applicationin più piccole configurazioni di caratteristiche, come WebConfig, DataJpaConfigecc Una configurazione completa funzionalità (misto web, dati, sicurezza ecc) causato anche i vostri fetta di prova test basati per non essere riuscito. Controlla i campioni di prova nel mio campione .

1

Penso che la soluzione migliore per questo problema sia allineare la struttura delle cartelle dei test con la struttura delle cartelle dell'applicazione.

Ho avuto lo stesso problema causato dalla duplicazione del mio progetto da un diverso progetto di struttura di cartelle.

se il tuo progetto di test e il tuo progetto applicativo avranno la stessa struttura non ti verrà richiesto di aggiungere annotazioni speciali alle tue classi di test e tutto funzionerà così com'è.


Ho avuto lo stesso errore e ho finalmente capito che il nome del pacchetto per la classe di test aveva una "regola" di battitura al posto di "regole". Dopo aver corretto il nome del pacchetto, l'errore è scomparso.
Gopal Bairwa,

1

Quando tutte le classi erano nello stesso pacchetto, le classi di test funzionavano. Non appena ho spostato tutte le classi java in pacchetti diversi per mantenere la struttura del progetto corretta, ho riscontrato lo stesso errore.

L'ho risolto fornendo il nome della mia classe principale nella classe di test come di seguito.

@SpringBootTest(classes=JunitBasicsApplication.class)

1

Ho avuto lo stesso problema e ho risolto aggiungendo una classe vuota annotata SpringBootApplicationnel pacchetto radice della cartella src / test / java

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

@SpringBootApplication
public class CoreTestConfiguration {}

0

Nel mio caso,
assicurati che il tuo ( test packagenome ) di YourApplicationTestssia equivalente al ( main packagenome ).


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

Le annotazioni sopra hanno funzionato bene per me. Sto usando lo stivale a molla con JPA.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.