Bei einem JpaTest konnte keine @ SpringBootConfiguration gefunden werden

183

Ich bin neu in Frameworks (habe gerade die Klasse bestanden) und benutze Spring Boot zum ersten Mal.

Ich versuche, einen einfachen Junit-Test durchzuführen, um festzustellen, ob meine CrudRepositories tatsächlich funktionieren.

Der Fehler, den ich immer wieder bekomme, ist:

Sie können keine @SpringBootConfiguration finden und müssen @ContextConfiguration oder @SpringBootTest (classes = ...) mit Ihrem Test java.lang.IllegalStateException verwenden

Konfiguriert sich Spring Boot nicht selbst?

Meine Testklasse:

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

 }

Mein Spring Boot-Anwendungsstarter:

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

        }
    }

Mein Repository:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}
Thomas Billet
quelle

Antworten:

263

In der Tat hat sich Spring Boot größtenteils selbst eingerichtet. Sie können wahrscheinlich bereits einen Großteil des von Ihnen geposteten Codes entfernen, insbesondere in Application.

Ich wünschte, Sie hätten die Paketnamen aller Ihrer Klassen oder zumindest die für Applicationund angegeben JpaTest. Das Besondere an @DataJpaTestund einige andere Anmerkungen sind, dass sie @SpringBootConfigurationim aktuellen Paket nach einer Anmerkung suchen. Wenn sie diese dort nicht finden können, durchlaufen sie die Pakethierarchie, bis sie sie finden.

Wenn beispielsweise der vollständig qualifizierte Name für Ihre Testklasse com.example.test.JpaTestund der für Ihre Anwendung lautete com.example.Application, kann Ihre Testklasse den @SpringBootApplication(und darin den @SpringBootConfiguration) finden.

Wenn sich die Anwendung in einem anderen Zweig der Pakethierarchie befindet, com.example.application.Applicationwird sie jedoch nicht gefunden.

Beispiel

Betrachten Sie das folgende Maven-Projekt:

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

Und dann der folgende Inhalt in Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Gefolgt von den Inhalten von JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Alles sollte funktionieren. Wenn Sie einen neuen Ordner mit dem src/main/com/exampleNamen " create" erstellen appund dann Ihren Ordner darin ablegen Application.java(und die packageDeklaration in der Datei aktualisieren ), wird beim Ausführen des Tests der folgende Fehler angezeigt:

java.lang.IllegalStateException: Sie konnten keine @SpringBootConfiguration finden und müssen für Ihren Test @ContextConfiguration oder @SpringBootTest (classes = ...) verwenden

Thomas Kåsene
quelle
1
Grüße, danke, dass Sie eine Lösung angeboten haben. Ich verwende das Maven-Paket-Setup mit einem anderen Paket für Tests und dem Anwendungscode. Wenn ich richtig interpretiere, sagen Sie, dass ich mein Testpaket an die Anwendungsklasse weiterleiten muss? und dann wird es die SpringConfiguration finden?
Thomas Billet
Wenn von „Maven Paket“ Sie „Modul“ bedeutet, dann ja, das Modul , in dem Sie Ihre Testklasse ist auf dem Modul muss abhängen , die Applicationin ist. Wenn jedoch meinen Sie src/mainund src/testdann die Ordner sind nicht Teil des Pakets Hierarchie. Vielleicht ist es besser, wenn Sie Ihre Frage nur mit einem Screenshot oder einer Erklärung Ihrer Projektstruktur aktualisieren.
Thomas Kåsene
Ich habe gerade das Problem gelöst, wie Sie sagten. Nach einigem googeln fand ich die vorgeschlagene Federpaketstruktur und überarbeitete sie alle. Jetzt laufen die Tests wie erwartet. Vielen Dank
Thomas Billet
Gut zu wissen! Ich habe die Antwort trotzdem mit einem ausführlicheren Beispiel aktualisiert.
Thomas Kåsene
3
+ - Test + - com + - Beispiel + - JpaTest.java funktioniert auch
user674158
104

Die Konfiguration ist an die Anwendungsklasse angehängt, sodass im Folgenden alles korrekt eingerichtet wird:

@SpringBootTest(classes = Application.class)

Beispiel aus dem JHipster-Projekt hier .

mrts
quelle
Dies scheint die perfekte Lösung zu sein. Ich muss keine Klasse oder Ordner verschieben.
Abhishek Aggarwal
21

Es lohnt sich zu überprüfen, ob Sie den Paketnamen Ihrer Hauptklasse mit Anmerkungen versehen haben @SpringBootApplication. In diesem Fall sollte sich der Testfall in einem geeigneten Paket befinden, andernfalls wird er im älteren Paket gesucht. das war bei mir der Fall.

Mohammed Rafeeq
quelle
11

Zusätzlich zu dem, was Thomas Kåsene gesagt hat, können Sie auch hinzufügen

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

in der Testanmerkung, um anzugeben, wo nach der anderen Klasse gesucht werden soll, wenn Sie Ihre Dateihierarchie nicht umgestalten möchten. Dies ist, was die Fehlermeldung andeutet, indem sie sagt:

Unable to find a @SpringBootConfiguration, you need to use 
@ContextConfiguration or @SpringBootTest(classes=...) ...
Cameron Gagnon
quelle
Dies ist eine sehr wertvolle Antwort! Vielen Dank, dass Sie @cameron!
Lance Kind
5

In meinem Fall waren die Pakete zwischen den Anwendungs- und Testklassen unterschiedlich

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

und

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

Nachdem sie sich einig waren, liefen die Tests korrekt.

Nick
quelle
5

Es funktioniert für mich

Der Paketname der obigen Testklasse wird in den Paketnamen der normalen Klasse geändert.

ändern Sie dies

Hang Gao
quelle
3

Die Testscheibe im Frühjahr Boot - 1.4 gebracht versehen Features orientierte Testfähigkeiten.

Beispielsweise,

@JsonTest bietet eine einfache Jackson-Umgebung zum Testen der JSON-Serialisierung und -Deserialisierung.

@WebMvcTest bietet eine nachgebildete Webumgebung, in der die Controller-Klasse für den Test angegeben und der MockMvc in den Test eingefügt werden kann.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest bereitet eine eingebettete Datenbank vor und bietet eine grundlegende JPA-Umgebung für den Test.

@RestClientTest bietet eine REST-Client-Umgebung für den Test, insbesondere den RestTemplateBuilder usw.

Diese Anmerkungen werden nicht mit SpringBootTest erstellt, sondern mit einer Reihe von AutoconfigureXXXund einer @TypeExcludesFilterAnmerkung kombiniert .

Schau es dir an @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 {}

Sie können Ihre Annotation @AutoconfigureXXX hinzufügen, um die Standardkonfiguration zu überschreiben.

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

Schauen wir uns Ihr Problem an.

  1. Mischen Sie nicht @DataJpaTestund erstellen Sie @SpringBootTest, wie oben erwähnt @DataJpaTest, die Konfiguration auf ihre eigene Weise (z. B. wird standardmäßig versucht, stattdessen ein eingebettetes H2 vorzubereiten) aus der Vererbung der Anwendungskonfiguration. @DataJpaTestist für Testscheibe bestimmt .
  2. Wenn Sie die Konfiguration von anpassen möchten @DataJpaTest, lesen Sie bitte diesen offiziellen Blogeintrag von Spring.io zu diesem Thema (etwas langweilig).
  3. Teilen Sie die Konfigurationen in Applicationin kleinere Konfigurationen von Features, wie WebConfig, DataJpaConfigetc. Eine voll funktionsfähige Konfiguration (Misch Web, Daten, Sicherheit usw.) auch Ihre verursacht Testscheibe basierte Tests nicht bestanden. Überprüfen Sie die Testproben in meiner Probe .
Hantsy
quelle
1

Ich denke, dass die beste Lösung für dieses Problem darin besteht, die Struktur Ihrer Testordner an der Struktur der Anwendungsordner auszurichten.

Ich hatte das gleiche Problem, das durch das Duplizieren meines Projekts aus einem anderen Ordnerstrukturprojekt verursacht wurde.

Wenn Ihr Testprojekt und Ihr Anwendungsprojekt dieselbe Struktur haben, müssen Sie Ihren Testklassen keine speziellen Anmerkungen hinzufügen, und alles funktioniert wie es ist.

Silber
quelle
Ich hatte den gleichen Fehler und fand schließlich heraus, dass der Paketname für die Testklasse einen Tippfehler "Regel" anstelle von "Regeln" hatte. Nach dem Korrigieren des Paketnamens ist der Fehler behoben.
Gopal Bairwa
1

Wenn sich alle Klassen im selben Paket befanden, funktionierten die Testklassen. Sobald ich alle Java-Klassen in ein anderes Paket verschoben habe, um die richtige Projektstruktur beizubehalten, wurde der gleiche Fehler angezeigt.

Ich habe es gelöst, indem ich meinen Hauptklassennamen in der Testklasse wie unten angegeben habe.

@SpringBootTest(classes=JunitBasicsApplication.class)
SumataPatil
quelle
1

Ich hatte das gleiche Problem und löste es durch Hinzufügen einer leeren Klasse, die SpringBootApplicationim Stammpaket des Ordners src / test / java mit Anmerkungen versehen ist

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

@SpringBootApplication
public class CoreTestConfiguration {}
Enrico Giurin
quelle
0

In meinem Fall
Stellen Sie sicher, dass Ihr ( test packageName ) von YourApplicationTestsdem ( main packageNamen ) entspricht.

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

Die obigen Anmerkungen haben bei mir gut funktioniert. Ich benutze Spring Boot mit JPA.

Umesh G.
quelle