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

186

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

Я пытаюсь запустить простой тест Junit, чтобы проверить, действительно ли работают мои CrudRepositories.

Ошибка, которую я продолжаю получать:

Не удается найти @SpringBootConfiguration, вам нужно использовать @ContextConfiguration или @SpringBootTest (classes = ...) с тестом 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 (classes = ...) с вашим тестом

Томас Козене
источник
1
Приветствую вас, спасибо за предложение решения. Я использую установку пакетов Maven, с другим пакетом для тестов и кодом приложения. Если я правильно понимаю, что вы говорите, что я должен направить свой тестовый пакет в класс приложения? и тогда он найдет SpringConfiguration?
Томас Биллет
Если под «maven package» вы подразумеваете «module», то да, модуль, в котором находится ваш тестовый класс, должен зависеть от того, в каком модуле он Applicationнаходится. Если, однако, вы имеете в виду src/mainи src/test, то эти папки не являются частью пакета иерархия. Возможно, вам лучше просто обновить вопрос с помощью скриншота или объяснения структуры вашего проекта.
Томас Козене
Я только что решил проблему, как вы сказали. после некоторого поиска в Google я нашел предложенную структуру пакета и реорганизовал их все. Теперь тесты выполняются, как и ожидалось. Большое спасибо
Томас Биллет
Хорошо, приятно знать! В любом случае я обновил ответ более подробным примером.
Томас Козене
3
+ - test + - com + - пример + - JpaTest.java также работает
user674158
106

Конфигурация привязана к классу приложения, поэтому следующее все настроит правильно:

@SpringBootTest(classes = Application.class)

Пример из проекта JHipster здесь .

MRTS
источник
Кажется, это идеальное решение. Мне не нужно перемещать какой-либо класс или папку.
Абхишек Аггарвал
21

Стоит проверить, не поменяли ли вы имя пакета вашего основного класса с пометкой @SpringBootApplication. В этом случае тестовый набор должен быть в соответствующей упаковке, в противном случае он будет искать его в старом пакете. это был случай для меня.

Мохаммед Рафик
источник
12

В дополнение к тому, что сказал Томас Козене, вы также можете добавить

@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

Тест срез при условии , весной ботинке 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и т. Д. Полнофункциональная конфигурация (смешанная сеть, данные, безопасность и т. Д.) Также привела к сбою тестов на основе тестового среза . Проверьте тестовые образцы в моем образце .
Hantsy
источник
1

Я думаю, что лучшее решение этой проблемы - выровнять структуру папок тестов со структурой папок приложения.

У меня была та же проблема, которая была вызвана дублированием моего проекта из проекта с другой структурой папок.

если ваш тестовый проект и проект приложения будут иметь одинаковую структуру, вам не потребуется добавлять какие-либо специальные аннотации к вашим тестовым классам, и все будет работать как есть.

Серебряный
источник
У меня была та же ошибка, и я наконец понял, что имя пакета для тестового класса содержит опечатку «rule» вместо «rules». После исправления имени пакета ошибка исчезла.
Гопал Баирва
1

Когда все классы были в одном пакете, тестовые классы работали. Как только я переместил все Java-классы в другой пакет для поддержания правильной структуры проекта, я получил ту же ошибку.

Я решил это, указав имя моего основного класса в тестовом классе, как показано ниже.

@SpringBootTest(classes=JunitBasicsApplication.class)
SumataPatil
источник
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имя ).

ahmednabil88
источник
-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.

Умеш Г
источник