Невозможно найти @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);
}
}
Ответы
Ответ 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{
}
Давайте посмотрим на вашу проблему,
- Не смешивайте
@DataJpaTest
и @SpringBootTest
, как сказано выше, @DataJpaTest
создаст конфигурацию по-своему (например, по умолчанию он попытается подготовить встроенную H2 вместо этого) из наследования конфигурации приложения. @DataJpaTest
предназначен для тестового среза. - Если вы хотите настроить конфигурацию
@DataJpaTest
, прочитайте эту официальную запись в блоге Spring.io по этой теме (немного утомительно). - Разделите конфигурации в
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.