Bir JpaTest yaparken @SpringBootConfiguration bulunamadı


186

Çerçevelerde yeniyim (sadece sınıfı geçtim) ve bu benim ilk kez Spring Boot'u kullanıyorum.

CrudRepositories'imin gerçekten çalışıp çalışmadığını görmek için basit bir Junit testi yapmaya çalışıyorum.

Ben almaya devam hata:

Bir @SpringBootConfiguration bulunamıyorsa, java.lang.IllegalStateException testinizle @ContextConfiguration veya @SpringBootTest (classes = ...) kullanmanız gerekir.

Spring Boot kendini yapılandırmıyor mu?

Test Sınıfım:

@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 uygulama başlatıcı:

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

        }
    }

Depom:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}

Yanıtlar:


264

Gerçekten de, Spring Boot çoğunlukla kendini kurdu. Muhtemelen, özellikle de yayınladığınız birçok koddan zaten kurtulabilirsiniz Application.

Hepinizin sınıfların paket isimlerini dahil, ya da en azından olanları için olsaydı Applicationve JpaTest. Hakkında @DataJpaTestve diğer birkaç ek @SpringBootConfigurationaçıklama, mevcut pakette bir ek açıklama aramaları ve orada bulamazlarsa, paket hiyerarşisini bulana kadar geçerler.

Örneğin, test sınıfınız için tam olarak nitelenmiş bir ad com.example.test.JpaTestve uygulamanız için bir ad com.example.Applicationolsaydı, test sınıfınız @SpringBootApplication(ve burada @SpringBootConfiguration) öğesini bulabilirdi.

Uygulama paket hiyerarşide farklı dalda ikamet Ancak, böyle com.example.application.Application, bu olur değil bulabilirsiniz.

Misal

Aşağıdaki Maven projesini düşünün:

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

Ve sonra aşağıdaki içerik Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Ardından içeriği JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Her şey çalışıyor olmalı. İçinde yeni bir klasör oluşturursanız src/main/com/exampledenilen appve ardından koymak Application.javaiçini onu (ve güncelleme packagedosyası içinde deklarasyon), testi çalıştıran size aşağıdaki hatayı verecektir:

java.lang.IllegalStateException: @SpringBootConfiguration bulunamıyor, testinizle @ContextConfiguration veya @SpringBootTest (classes = ...) kullanmanız gerekir


1
Selamlar, bir çözüm sunduğunuz için teşekkür ederim Maven paket kurulumunu kullanıyorum, testler ve uygulama kodu için farklı bir paketle. Eğer u ne diyorsun doğru yorumlamak, Test Paketimi Uygulama sınıfına yönlendirmek zorunda mı? ve sonra SpringConfiguration?
Thomas Billet

Eğer "modülü" demek "maven paket" ile, o zaman evet, test sınıfı olduğu modül modül bağlıdır zorunda kalırsa Application. If olduğunu, ancak, demek src/mainve src/testdaha sonra bu klasörleri paketin bir parçası değildir, hiyerarşi. Belki de sorunuzu sadece bir ekran görüntüsü ile güncellemeniz veya proje yapınızın nasıl bir şey olduğu konusunda daha iyi olursunuz.
Thomas Kåsene

Dediğin gibi sorunu çözdüm. Bazı googling sonra önerilen bahar paket yapısını buldum ve hepsini yeniden düzenledi. Şimdi testler beklendiği gibi çalışıyor. Çok teşekkürler
Thomas Billet

Tamam, bilmek güzel! Cevabı zaten daha kapsamlı bir örnekle güncelledim.
Thomas Kåsene

3
+ - test + - com + - örnek + - JpaTest.java ayrıca çalışır
user674158

106

Yapılandırma uygulama sınıfına eklenmiştir, bu nedenle aşağıdakiler her şeyi doğru şekilde ayarlayacaktır:

@SpringBootTest(classes = Application.class)

Buradaki JHipster projesinden bir örnek .


Bu mükemmel bir çözüm gibi görünüyor. Sınıf veya klasör taşımam gerekmiyor.
Abhishek Aggarwal

21

Ana sınıfınızın ek açıklama eklenmiş paket adını değiştirip değiştirmediğinizi kontrol etmeye değer @SpringBootApplication. Bu durumda, test çantası uygun bir pakette olmalıdır, aksi takdirde eski pakette arayacaktır. benim için durum buydu.


12

Thomas Kåsene'nin söylediklerine ek olarak,

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

dosya hiyerarşinizi yeniden düzenlemek istemiyorsanız, diğer sınıfı nerede arayacağını belirtmek için test ek açıklamasına yönlendirin. Hata mesajının söylediği şey şudur:

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

Bu çok değerli bir cevap! Teşekkürler @cameron!
Lance Kind

6

Benim durumumda paketler Uygulama ve Test sınıfları arasında farklıydı

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

ve

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

Onları kabul ettikten sonra testler doğru bir şekilde gerçekleştirildi.


5

Benim için çalışıyor

yukarıdaki test sınıfının paket adı, normal sınıfın paket adıyla aynı olarak değiştirilir.

buna değiştir


3

Test dilim Yay Boot 1.4 getirilen sağlanan özelliği odaklı Test yetenekleri.

Örneğin,

@JsonTest , json serileştirmesini ve serileştirmesini test etmek için basit bir Jackson ortamı sağlar.

@ WebMvcTest sahte bir web ortamı sağlar, test için denetleyici sınıfını belirtebilir ve teste MockMvc enjekte edebilir.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest katıştırılmış bir veritabanı hazırlar ve test için temel JPA ortamı sağlar.

@RestClientTest test için REST istemci ortamı sağlar, esp RestTemplateBuilder vb.

Bu ek açıklamalar SpringBootTest ile oluşturulmaz, bir dizi AutoconfigureXXXve bir@TypeExcludesFilter ek açıklamaları.

Bir bak @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 {}

Varsayılan yapılandırmayı geçersiz kılmak için @AutoconfigureXXX ek açıklamanızı ekleyebilirsiniz.

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

Sorununuza bir göz atalım,

  1. Karıştırmayın @DataJpaTestve @SpringBootTestyukarıda belirtildiği gibi @DataJpaTestyapılandırmayı kendi yöntemiyle oluşturacaktır (örneğin, varsayılan olarak, bunun yerine gömülü bir H2 hazırlamaya çalışacaktır), uygulama yapılandırma mirasından. test dilimi@DataJpaTest için belirlenmiştir .
  2. Yapılandırmasını özelleştirmek istiyorsanız @DataJpaTest, lütfen bu konu için Spring.io'dan bu resmi blog girişini okuyun (biraz sıkıcı).
  3. Yapılandırmaları , vb. ApplicationGibi özelliklere göre daha küçük yapılandırmalara bölün . Tam özellikli bir yapılandırma (karışık web, veri, güvenlik vb.) Ayrıca test dilimi tabanlı testlerinizin başarısız olmasına neden oldu. Kontrol test örneklerini de benim numunenin .WebConfigDataJpaConfig

1

Bu sorun için en iyi çözüm, test klasörleri yapınızı uygulama klasörü yapısı ile hizalamak olduğunu düşünüyorum.

Projemi farklı bir klasör yapısı projesinden çoğaltmanın neden olduğu aynı sorunu yaşadım.

test projeniz ve uygulama projeniz aynı yapıya sahip olacaksa, test sınıflarınıza özel ek açıklamalar eklemeniz gerekmeyecek ve her şey olduğu gibi çalışacaktır.


Aynı hatayla karşılaştım ve sonunda test sınıfı için paket adının "kurallar" yerine bir yazım hatası "kuralı" olduğunu anladım. Paket adını düzelttikten sonra hata ortadan kalktı.
Gopal Bairwa

1

Tüm sınıflar aynı pakette olduğunda, test sınıfları çalışıyordu. Uygun proje yapısını korumak için tüm java sınıflarını farklı pakete taşıdığımda aynı hatayı alıyordum.

Aşağıdaki gibi test sınıfında ana sınıf adımı vererek çözdüm.

@SpringBootTest(classes=JunitBasicsApplication.class)

1

Aynı sorunu yaşadım ve src / test / javaSpringBootApplication klasörünün kök paketinde açıklamalı boş bir sınıf ekleyerek çözdüm

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

@SpringBootApplication
public class CoreTestConfiguration {}

0

Benim durumda
olduğundan emin olun ( test packageisim ) ait YourApplicationTests(eşdeğerdir main packageisim ).


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

Yukarıdaki ek açıklamalar benim için iyi çalıştı. JPA ile yaylı bot kullanıyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.