Không thể tìm thấy @SpringBootConfiguration khi thực hiện JpaTest


183

Tôi chưa quen với các khung công tác (vừa qua lớp) và đây là lần đầu tiên tôi sử dụng Spring Boot.

Tôi đang cố gắng chạy thử nghiệm Junit đơn giản để xem CrudRepositories của tôi có thực sự hoạt động không.

Lỗi tôi tiếp tục nhận được là:

Không thể tìm thấy @SpringBootConfiguration, bạn cần sử dụng @ContextConfiguration hoặc @SpringBootTest (class = ...) với bài kiểm tra java.lang.IllegalStateException của bạn

Spring Boot không tự cấu hình?

Lớp kiểm tra của tôi:

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

 }

Khởi động ứng dụng Spring Boot của tôi:

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

        }
    }

Kho lưu trữ của tôi:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}

Câu trả lời:


263

Thật vậy, Spring Boot tự thiết lập phần lớn. Bạn có thể đã có thể thoát khỏi rất nhiều mã bạn đã đăng, đặc biệt là trong Application.

Tôi ước bạn đã bao gồm tên gói của tất cả các lớp của bạn, hoặc ít nhất là các tên cho ApplicationJpaTest. Điều về @DataJpaTestvà một vài chú thích khác là họ tìm kiếm một @SpringBootConfigurationchú thích trong gói hiện tại và nếu họ không thể tìm thấy nó ở đó, họ đi qua hệ thống phân cấp gói cho đến khi họ tìm thấy nó.

Ví dụ: nếu tên đủ điều kiện cho lớp kiểm tra của bạn là com.example.test.JpaTestvà tên cho ứng dụng của bạn là com.example.Application, thì lớp kiểm tra của bạn sẽ có thể tìm thấy @SpringBootApplication(và trong đó, @SpringBootConfiguration).

Tuy nhiên, nếu ứng dụng nằm trong một nhánh khác của hệ thống phân cấp gói, tuy nhiên, như thế com.example.application.Application, nó sẽ không tìm thấy nó.

Thí dụ

Hãy xem xét dự án Maven sau:

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

Và sau đó là nội dung sau Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Tiếp theo là nội dung của JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Mọi thứ nên được làm việc. Nếu bạn tạo một thư mục mới bên trong src/main/com/exampleđược gọi app, sau đó đặt Application.javabên trong nó (và cập nhật packagekhai báo bên trong tệp), chạy thử nghiệm sẽ cho bạn lỗi sau:

java.lang.IllegalStateException: Không thể tìm thấy @SpringBootConfiguration, bạn cần sử dụng @ContextConfiguration hoặc @SpringBootTest (class = ...) với bài kiểm tra của bạn


1
Xin chào, cảm ơn bạn đã cung cấp giải pháp Đang sử dụng cài đặt gói Maven, với một gói khác để kiểm tra và mã ứng dụng. Nếu tôi diễn giải đúng những gì bạn đang nói, tôi có phải chuyển Gói kiểm tra của mình đến lớp Ứng dụng không? và sau đó nó sẽ tìm thấy SpringConfiguration?
Thomas Billet

Nếu bởi "maven gói" bạn có nghĩa là "mô-đun", sau đó có, các module trong đó lớp thử nghiệm của bạn là phải phụ thuộc vào các mô-đun mà Applicationlà ở. Tuy nhiên, nếu bạn có ý nghĩa src/mainsrc/test, sau đó các thư mục không phải là một phần của gói hệ thống cấp bậc. Có lẽ bạn tốt hơn hết là chỉ cập nhật câu hỏi của bạn bằng một ảnh chụp màn hình hoặc giải thích về cấu trúc dự án của bạn.
Thomas Kåsene

Tôi chỉ giải quyết vấn đề như bạn nói. Sau khi một số googling tôi tìm thấy cấu trúc gói mùa xuân được đề xuất và tái cấu trúc tất cả chúng. Bây giờ các bài kiểm tra chạy như mong đợi. Cảm ơn rất nhiều
Thomas Billet

Được rồi, tốt để biết! Tôi đã cập nhật câu trả lời với một ví dụ kỹ lưỡng hơn.
Thomas Kåsene

3
+ - test + - com + - ví dụ + - JpaTest.java cũng hoạt động
user674158

104

Cấu hình được gắn vào lớp ứng dụng, do đó, phần sau sẽ thiết lập mọi thứ chính xác:

@SpringBootTest(classes = Application.class)

Ví dụ từ dự án JHipster ở đây .


Đây dường như là giải pháp hoàn hảo. Tôi không cần phải di chuyển bất kỳ lớp học hoặc thư mục.
Abhishek Aggarwal

21

Rất đáng để kiểm tra xem bạn có tên gói được cấu trúc lại của lớp chính của bạn được chú thích hay không @SpringBootApplication. Trong trường hợp đó, testcase phải ở trong một gói thích hợp nếu không nó sẽ tìm kiếm nó trong gói cũ hơn. đây là trường hợp của tôi


11

Ngoài những gì Thomas Kåsene nói, bạn cũng có thể thêm

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

vào chú thích kiểm tra để chỉ định nơi cần tìm lớp khác nếu bạn không muốn cấu trúc lại cấu trúc phân cấp tệp của mình. Đây là những gì thông báo lỗi gợi ý bằng cách nói:

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

Đây là một câu trả lời rất có giá trị! Cảm ơn bạn @cameron!
Lance Kind

5

Trong trường hợp của tôi, các gói khác nhau giữa các lớp Ứng dụng và Kiểm tra

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

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

Sau khi làm cho họ đồng ý các bài kiểm tra chạy chính xác.


5

Nó làm việc cho tôi

tên gói của lớp kiểm tra trên được thay đổi thành giống như tên gói của lớp bình thường.

thay đổi điều này


3

Các lát thử nghiệm được cung cấp trong mùa xuân Boot 1.4 mang tính năng khả năng kiểm tra định hướng.

Ví dụ,

@JsonTest cung cấp một môi trường Jackson đơn giản để kiểm tra tuần tự hóa và giải tuần tự json.

@WebMvcTest cung cấp một môi trường web giả, nó có thể chỉ định lớp trình điều khiển để kiểm tra và đưa MockMvc vào kiểm tra.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest sẽ chuẩn bị một cơ sở dữ liệu nhúng và cung cấp môi trường JPA cơ bản cho thử nghiệm.

@RestClientTest cung cấp môi trường máy khách REST cho thử nghiệm, đặc biệt là RestTemplateBuilder, v.v.

Các chú thích này không được soạn với SpringBootTest, chúng được kết hợp với một loạt các chú thích AutoconfigureXXXvà một @TypeExcludesFilterchú thích.

Có một cái nhìn vào @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 {}

Bạn có thể thêm chú thích @AutoconfigureXXX của mình để ghi đè cấu hình mặc định.

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

Hãy xem xét vấn đề của bạn,

  1. Không trộn lẫn @DataJpaTest@SpringBootTest, như đã nói ở trên @DataJpaTestsẽ xây dựng cấu hình theo cách riêng của nó (ví dụ: theo mặc định, nó sẽ cố gắng chuẩn bị một H2 nhúng thay thế) từ kế thừa cấu hình ứng dụng. @DataJpaTestđược chỉ định cho lát thử nghiệm .
  2. Nếu bạn muốn tùy chỉnh cấu hình của @DataJpaTest, vui lòng đọc mục blog chính thức này từ Spring.io cho chủ đề này, (một chút tẻ nhạt).
  3. Chia các cấu hình Applicationthành các cấu hình nhỏ hơn theo các tính năng, chẳng hạn như WebConfig, DataJpaConfigvv Một cấu hình đầy đủ tính năng (web hỗn hợp, dữ liệu, bảo mật, v.v.) cũng khiến các bài kiểm tra dựa trên lát thử nghiệm của bạn bị thất bại. Kiểm tra các mẫu thử trong mẫu của tôi .

1

Tôi nghĩ rằng giải pháp tốt nhất cho vấn đề này là căn chỉnh cấu trúc thư mục kiểm tra của bạn với cấu trúc thư mục ứng dụng.

Tôi đã có cùng một vấn đề gây ra bằng cách sao chép dự án của tôi từ một dự án cấu trúc thư mục khác.

nếu dự án thử nghiệm của bạn và dự án ứng dụng của bạn sẽ có cùng cấu trúc, bạn sẽ không bắt buộc phải thêm bất kỳ chú thích đặc biệt nào vào các lớp thử nghiệm của mình và mọi thứ sẽ hoạt động như bình thường.


Tôi đã có cùng một lỗi và cuối cùng tôi đã tìm ra rằng tên gói cho lớp kiểm tra có một "quy tắc" lỗi chính tả thay cho "quy tắc". Sau khi sửa tên gói, lỗi đã biến mất.
Gopal Bairwa

1

Khi tất cả các lớp trong cùng một gói, các lớp kiểm tra đã hoạt động. Ngay khi tôi chuyển tất cả các lớp java sang gói khác để duy trì cấu trúc dự án phù hợp, tôi đã gặp cùng một lỗi.

Tôi đã giải quyết nó bằng cách cung cấp tên lớp chính của tôi trong lớp kiểm tra như bên dưới.

@SpringBootTest(classes=JunitBasicsApplication.class)

1

Tôi đã có cùng một vấn đề và tôi đã giải quyết bằng cách thêm một lớp trống được chú thích SpringBootApplicationtrong gói gốc của thư mục src / test / java

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

@SpringBootApplication
public class CoreTestConfiguration {}

0

Trong trường hợp của tôi,
hãy đảm bảo ( test packagetên ) của bạn YourApplicationTeststương đương với ( main packagetên ).


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

Các chú thích trên làm việc tốt cho tôi. Tôi đang sử dụng boot mùa xuân với JPA.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.