Tidak dapat menemukan @SpringBootConfiguration saat melakukan JpaTest

185

Saya baru menggunakan frameworks (baru saja lulus kelas) dan ini adalah pertama kalinya saya menggunakan Spring Boot.

Saya mencoba menjalankan tes Junit sederhana untuk melihat apakah CrudRepositori saya memang berfungsi.

Kesalahan yang terus saya dapatkan adalah:

Tidak dapat menemukan @SpringBootConfiguration, Anda perlu menggunakan @ContextConfiguration atau @SpringBootTest (kelas = ...) dengan java.lang.IllegalStateException pengujian Anda

Tidak Spring Boot mengkonfigurasi sendiri?

Kelas Tes Saya:

@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 aplikasi Spring Boot saya:

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

        }
    }

Repositori Saya:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}
Thomas Billet
sumber

Jawaban:

264

Memang, Boot Musim Semi memang mengatur sendiri sebagian besar. Anda mungkin sudah bisa menyingkirkan banyak kode yang Anda posting, terutama di Application.

Saya harap Anda memasukkan nama paket semua kelas Anda, atau setidaknya yang untuk Applicationdan JpaTest. Masalahnya @DataJpaTestdan beberapa anotasi lainnya adalah mereka mencari @SpringBootConfigurationanotasi dalam paket saat ini, dan jika mereka tidak dapat menemukannya di sana, mereka melintasi hierarki paket hingga mereka menemukannya.

Misalnya, jika nama yang sepenuhnya memenuhi syarat untuk kelas tes Anda adalah com.example.test.JpaTestdan yang untuk aplikasi Anda adalah com.example.Application, maka kelas tes Anda akan dapat menemukan @SpringBootApplication(dan di dalamnya, the @SpringBootConfiguration).

Jika aplikasi tinggal di cabang yang berbeda dari hirarki paket, namun, seperti com.example.application.Application, itu akan tidak menemukannya.

Contoh

Pertimbangkan proyek Maven berikut:

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

Dan kemudian konten berikut di Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Diikuti dengan isi JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Semuanya harus berfungsi. Jika Anda membuat folder baru di dalamnya src/main/com/examplebernama app, dan kemudian meletakkannya Application.javadi dalamnya (dan memperbarui packagedeklarasi di dalam file), menjalankan tes akan memberi Anda kesalahan berikut:

java.lang.IllegalStateException: Tidak dapat menemukan @SpringBootConfiguration, Anda perlu menggunakan @ContextConfiguration atau @SpringBootTest (kelas = ...) dengan pengujian Anda

Thomas Kåsene
sumber
1
Salam, terima kasih telah menawarkan solusi Saya menggunakan pengaturan paket Maven, dengan paket berbeda untuk tes dan kode aplikasi. Jika saya mengartikan dengan benar apa yang Anda katakan adalah, Bahwa saya harus mengarahkan Paket Tes saya ke kelas Aplikasi? dan kemudian akan menemukan SpringConfiguration?
Thomas Billet
Jika dengan "paket maven" yang Anda maksud "modul", maka ya, modul di mana kelas tes Anda harus bergantung pada modul yang Applicationada. Jika, bagaimanapun, maksud Anda src/maindan src/test, maka folder itu bukan bagian dari paket hirarki. Mungkin Anda lebih baik memperbarui pertanyaan Anda dengan tangkapan layar atau penjelasan seperti apa struktur proyek Anda.
Thomas Kåsene
Saya baru saja menyelesaikan masalah seperti yang Anda katakan. setelah beberapa googling saya menemukan struktur paket pegas yang disarankan dan refactored semuanya. Sekarang tes berjalan seperti yang diharapkan. Terima kasih banyak
Thomas Billet
Baiklah, bagus untuk tahu! Saya memperbarui jawabannya dengan contoh yang lebih teliti.
Thomas Kåsene
3
+ - test + - com + - example + - JpaTest.java juga berfungsi
user674158
106

Konfigurasi dilampirkan ke kelas aplikasi, jadi yang berikut ini akan mengatur semuanya dengan benar:

@SpringBootTest(classes = Application.class)

Contoh dari proyek JHipster di sini .

Tuan
sumber
Ini tampaknya menjadi solusi yang sempurna. Saya tidak perlu memindahkan kelas atau folder apa pun.
Abhishek Aggarwal
21

Penting untuk memeriksa apakah Anda memiliki nama paket yang dire-refoured dari kelas utama Anda yang dianotasi @SpringBootApplication. Dalam hal ini testcase harus dalam paket yang sesuai jika tidak maka akan mencarinya dalam paket yang lebih lama. ini adalah kasus bagi saya.

Mohammed Rafeeq
sumber
11

Selain apa yang dikatakan Thomas Kåsene, Anda juga dapat menambahkan

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

ke anotasi tes untuk menentukan di mana seharusnya mencari kelas lain jika Anda tidak ingin refactor hierarki file Anda. Inilah yang pesan kesalahan mengisyaratkan dengan mengatakan:

Unable to find a @SpringBootConfiguration, you need to use 
@ContextConfiguration or @SpringBootTest(classes=...) ...
Cameron Gagnon
sumber
Ini jawaban yang sangat berharga! @Cameron terima kasih!
Lance Kind
6

Dalam kasus saya, paketnya berbeda antara kelas Aplikasi dan Tes

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

dan

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

Setelah membuat mereka setuju tes berjalan dengan benar.

Nick
sumber
5

Ini bekerja untuk saya

nama paket dari kelas tes di atas diubah sama dengan nama paket dari kelas normal.

ubah ke ini

hang gao
sumber
3

The uji slice disediakan di Spring Boot 1.4 membawa fitur uji kemampuan berorientasi.

Sebagai contoh,

@JsonTest menyediakan lingkungan Jackson sederhana untuk menguji serialisasi dan deserialisasi json.

@WebMvcTest menyediakan lingkungan web tiruan, ini dapat menentukan kelas controller untuk pengujian dan menyuntikkan MockMvc dalam pengujian.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@ DataJpaTest akan menyiapkan basis data tertanam dan menyediakan lingkungan JPA dasar untuk pengujian.

@RestClientTest menyediakan lingkungan klien REST untuk pengujian, khususnya RestTemplateBuilder dll.

Anotasi ini tidak disusun dengan SpringBootTest, mereka digabungkan dengan serangkaian AutoconfigureXXX dan @TypeExcludesFilteranotasi.

Lihatlah @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 {}

Anda dapat menambahkan anotasi @AutoconfigureXXX Anda untuk mengabaikan konfigurasi default.

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

Mari kita lihat masalah Anda,

  1. Jangan campur @DataJpaTestdan @SpringBootTest, seperti yang dikatakan di atas @DataJpaTestakan membangun konfigurasi dengan caranya sendiri (mis. Secara default, itu akan mencoba untuk menyiapkan H2 tertanam sebagai gantinya) dari warisan konfigurasi aplikasi. @DataJpaTestditujukan untuk uji slice .
  2. Jika Anda ingin menyesuaikan konfigurasi @DataJpaTest, baca entri blog resmi ini dari Spring.io untuk topik ini, (sedikit membosankan).
  3. Membagi konfigurasi Applicationmenjadi konfigurasi yang lebih kecil dengan fitur, seperti WebConfig, DataJpaConfigdll. Konfigurasi berfitur lengkap (web campuran, data, keamanan dll) juga menyebabkan tes berbasis uji slice Anda gagal. Periksa sampel uji dalam sampel saya .
Hantsy
sumber
1

Saya pikir solusi terbaik untuk masalah ini adalah menyelaraskan struktur folder tes Anda dengan struktur folder aplikasi.

Saya memiliki masalah yang sama yang disebabkan oleh duplikasi proyek saya dari proyek struktur folder yang berbeda.

jika proyek pengujian Anda dan proyek aplikasi Anda akan memiliki struktur yang sama, Anda tidak akan diharuskan untuk menambahkan anotasi khusus ke kelas pengujian Anda dan semuanya akan berjalan sebagaimana mestinya.

perak
sumber
Saya memiliki kesalahan yang sama dan akhirnya saya tahu bahwa nama paket untuk kelas tes memiliki "aturan" salah ketik "aturan". Setelah memperbaiki nama paket, kesalahan hilang.
Gopal Bairwa
1

Ketika semua kelas berada dalam paket yang sama, kelas tes bekerja. Segera setelah saya memindahkan semua kelas java ke paket yang berbeda untuk mempertahankan struktur proyek yang tepat, saya mendapatkan kesalahan yang sama.

Saya menyelesaikannya dengan memberikan nama kelas utama saya di kelas tes seperti di bawah ini.

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

Saya memiliki masalah yang sama dan saya menyelesaikannya dengan menambahkan kelas kosong yang dijelaskan SpringBootApplicationdalam paket root dari folder src / test / java

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

@SpringBootApplication
public class CoreTestConfiguration {}
Enrico Giurin
sumber
0

Dalam kasus saya
Pastikan ( test packagenama ) Anda YourApplicationTestssama dengan ( main packagenama ).

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

Penjelasan di atas bekerja dengan baik untuk saya. Saya menggunakan spring boot dengan JPA.

Umesh G
sumber