Неможливо знайти @SpringBootConfiguration при виконанні JpaTest


185

Я новачок у фреймворках (щойно пройшов клас), і це вперше я використовую Spring Boot.

Я намагаюся запустити простий тест Junit, щоб перевірити, чи справді працюють мої CrudRepositories.

Помилка, яку я постійно отримую:

Неможливо знайти @SpringBootConfiguration, вам потрібно використовувати @ContextConfiguration або @SpringBootTest (класи = ...) з вашим тестом java.lang.IllegalStateException

Чи не налаштовується Spring Boot?

Мій тестовий клас:

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

 }

Мій пусковий додаток 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);         

        }
    }

Мій сховище:

public interface AccountRepository extends CrudRepository<Account,Long> {

    public Account findByUsername(String username);

    }
}

Відповіді:


264

Дійсно, Spring Boot здебільшого налаштований на себе. Ви, ймовірно, вже можете позбутися від багатьох опублікованих вами кодів, особливо в Application.

Я хотів би, щоб ви включили назви пакетів усіх своїх класів, або, принаймні, для Applicationта та JpaTest. Справа @DataJpaTestта кілька інших приміток полягає в тому, що вони шукають @SpringBootConfigurationанотацію в поточному пакеті, і якщо вони не можуть її знайти там, вони переміщують ієрархію пакунків, поки не знайдуть його.

Наприклад, якщо повне кваліфіковане ім’я для вашого тестового класу було com.example.test.JpaTestі ім'я для вашої заявки com.example.Application, то ваш тестовий клас зможе знайти @SpringBootApplication(і в ньому - @SpringBootConfiguration).

Якби програма знаходилася в іншій гілці ієрархії пакунків, однак, як-от com.example.application.Application, вона не знайшла б її.

Приклад

Розглянемо наступний проект Maven:

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

А потім наступний вміст у Application.java:

package com.example;

@SpringBootApplication
public class Application {

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

Після цього вміст JpaTest.java:

package com.example.test;

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

    @Test
    public void testDummy() {
    }
}

Все повинно працювати. Якщо ви створите нову папку всередині, яку src/main/com/exampleназивають app, а потім помістите Application.javaїї всередину (та оновите packageдекларацію всередині файлу), запуск тесту дасть вам таку помилку:

java.lang.IllegalStateException: Неможливо знайти @SpringBootConfiguration, вам потрібно використовувати @ContextConfiguration або @SpringBootTest (класи = ...) для вашого тесту


1
Вітаю, дякую за те, що ви запропонували рішення Am, використовуючи налаштування пакету Maven, з іншим пакетом для тестів та кодом програми. Якщо я правильно тлумачу, що ви говорите, це те, що я повинен спрямовувати свій тестовий пакет до класу Application? і тоді він знайде SpringConfiguration?
Томас Біллет

Якщо під "пакетом maven" ви маєте на увазі "модуль", то так, модуль, у якому є ваш тестовий клас, повинен залежати від модуля, який Applicationє. Якщо, однак, ви маєте на увазі src/mainі src/test, то ці папки не є частиною пакету ієрархія. Можливо, вам краще просто оновити своє запитання скріншотом або поясненням того, як виглядає ваша структура проекту.
Thomas Kåsene

Я просто вирішив проблему, як ви сказали. після деякого гуглінгу я знайшов запропоновану структуру пакетів весни та відновив їх усі. Зараз випробування проходять так, як очікувалося. Дякую багато
Томас Біллет

Добре, добре знати! Я все-таки оновив відповідь більш ретельним прикладом.
Thomas Kåsene

3
+ - test + - com + - example + - також працює
JpaTest.java

105

Конфігурація додається до класу додатків, тому нижче буде налаштовано все правильно:

@SpringBootTest(classes = Application.class)

Приклад проекту JHipster тут .


Це здається ідеальним рішенням. Мені не потрібно переміщувати жоден клас чи папку.
Абхішек Агарвал

21

Варто перевірити, чи є у вас позначені рефакторні назви основного класу @SpringBootApplication. У такому випадку тестова шафа повинна знаходитися у відповідній упаковці, інакше вона шукатиме її у старій упаковці. це було для мене.


11

Окрім того, що сказав Томас Кесен, ви можете також додати

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

до тестової анотації, щоб вказати, де він повинен шукати інший клас, якщо ви не хочете переробляти ієрархію файлів. На це натякає повідомлення про помилку, кажучи:

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

Це дуже цінна відповідь! Дякую @cameron!
Lance Kind

6

У моєму випадку пакети відрізнялися між класами Application та Test

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

і

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

Після того, як вони погодилися, тести пройшли правильно.


5

Це працює для мене

назва пакета вищевказаного тестового класу змінюється на те саме, що назва пакету звичайного класу.

зміни до цього


3

Випробування скибочку передбачений в Spring завантажувальних 1,4 принесли художні орієнтовані можливості тестування.

Наприклад,

@JsonTest забезпечує просте середовище Джексона для тестування серіалізації та десеріалізації json.

@WebMvcTest надає макет веб-середовища, він може вказати клас контролера для тесту та ввести MockMvc у тест.

@WebMvcTest(PostController.class)
public class PostControllerMvcTest{

    @Inject MockMvc mockMvc;

}

@DataJpaTest підготує вбудовану базу даних та забезпечує базове середовище JPA для тесту.

@RestClientTest забезпечує клієнтське середовище REST для тестування, особливо RestTemplateBuilder тощо.

Ці анотації не складаються із SpringBootTest, вони поєднуються із серією AutoconfigureXXXта @TypeExcludesFilterанотаціями.

Погляньте @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 {}

Ви можете додати свою примітку @AutoconfigureXXX, щоб змінити конфігурацію за замовчуванням.

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

Давайте подивимось на вашу проблему,

  1. Не змішуйте, @DataJpaTestі @SpringBootTest, як було сказано вище, @DataJpaTestбуде створено конфігурацію по-своєму (наприклад, за замовчуванням, вона спробує підготувати вбудований H2) замість спадщини конфігурації програми. @DataJpaTestпризначений для тестового шматочка .
  2. Якщо ви хочете налаштувати конфігурацію @DataJpaTest, прочитайте цей офіційний запис у блозі від Spring.io для цієї теми (трохи нудно).
  3. Розділити конфігурації в Applicationбільш дрібні конфігурації з допомогою функцій, таких як WebConfig, і DataJpaConfigт.д. повнофункціональної конфігурації (змішана мережа, дані, безпеку і т.д.) також викликав ваш тест зрізів тести , засновані не відбувся. Перевірте тестові зразки в моєму зразку .

1

Я думаю, що найкраще рішення цього питання - вирівняти структуру папок тестів із структурою папок додатків.

У мене була та сама проблема, яка була викликана дублюванням мого проекту з іншого проекту структури структури папок.

якщо ваш тестовий проект та проект вашої програми матимуть однакову структуру, від вас не буде потрібно додавати жодних спеціальних приміток до ваших тестових класів, і все працюватиме як є.


У мене була така ж помилка, і я нарешті з'ясував, що назва пакету для тестового класу замість "правил" мала помилку "правило". Після виправлення назви пакета помилка пішла.
Gopal Bairwa

1

Коли всі класи були в одному пакеті, тестові класи працювали. Як тільки я перемістив усі класи Java на інший пакет, щоб підтримувати належну структуру проекту, у мене з’явилася однакова помилка.

Я вирішив це, вказавши своє основне ім’я в тестовому класі, як показано нижче.

@SpringBootTest(classes=JunitBasicsApplication.class)

1

У мене була така ж проблема, і я вирішив, додавши порожній клас із зауваженням SpringBootApplicationу кореневий пакет папки src / test / java

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

@SpringBootApplication
public class CoreTestConfiguration {}

0

У моєму випадку
переконайтесь, що ваше ( test packageім’я ) YourApplicationTestsеквівалентне ( main packageім'я )


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

Вище анотації спрацювали для мене добре. Я використовую весняне завантаження з JPA.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.