Подтвердить что ты не робот

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

Я новичок в фреймворках (только что прошел класс), и я впервые использую 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);

    }
}
4b9b3361

Ответ 1

Действительно, 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 =...) с вашим тестом

Ответ 2

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

@SpringBootTest(classes = Application.class)

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

Ответ 3

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

Ответ 4

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

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

в тестовую аннотацию, чтобы указать, где он должен искать другой класс, если вы не хотите реорганизовывать свою иерархию файлов. Это то, о чем подсказывает сообщение об ошибке:

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

Ответ 5

В моем случае пакеты были разными для классов Application и Test.

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

а также

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

После того, как они согласились, тесты прошли правильно.

Ответ 6

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

Ответ 7

Это работает для меня

имя пакета вышеупомянутого тестового класса изменяется на то же самое, что и имя пакета обычного класса.

изменить на это

Ответ 8

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

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

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

Ответ 9

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

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

@SpringBootTest (классы = JunitBasicsApplication.class)

Надеюсь это поможет.!!

Ответ 10

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.