Как загрузить в тесте загрузки Spring Базовое приложение Spring-Контекст, Добавляя только Именованные компоненты?

#java #spring-boot #components #integration-testing #applicationcontext

Вопрос:

Оригинал

Я пытаюсь загрузить в тесте приложения Spring Boot (v2.3.8) только именованные компоненты в базовом контексте приложения Spring. Более конкретно, я хочу загрузить в тесте контекст приложения Spring, который настраивает, по крайней мере, ведение журнала, загрузку внешних свойств, проверку (через API проверки Java) и @Value подключение, но без MVC, JPA данных и т. Д. По сути, я хочу протестировать через интерфейс с аннотацией ограничений (например @NotBlank ), @Service который использует только локальную файловую систему (без MVC, JPA данных или любого другого «среза» теста загрузки Spring) и заполняет один элемент данных @Value .

Я безрезультатно пробовал множество аннотаций (и некоторые из присущих им атрибутов) в различных комбинациях-подмножествах: например @SpringBootTest , @Configuration , @ContextConfiguration , @TestConfiguration , @TypeExcludeFilters , и т. Д. Например:

 @Validated public interface SomeService {  String someMethod (@NotBlank String someParam); } ... @Service public class SomeServiceImpl implements SomeService {   @Value("${some.value}")  private String someValue;   @Override  public String someMethod(String someParam) {  // do something with local file-system,  // with someValue in hand, and  // knowing someParam not blank  } } ... @SpringBootTest(classes={SomeServiceImpl.class},webEnvironment=WebEnvironment.NONE) class SomeServiceTests {   @Autowired  private SomeService someService;   @Test  void throwConstraintViolationException_whenSomeParamNil() {  assertThrows(  ConstraintViolationException.class,  ()-gt;someService.someMethod(new String()));  }  ... }  

В этом примере атрибут classes @SpringBootTest загружает указанный класс, но скрывает все основы (ведение журнала, проверка и т. Д.), Которые я также ищу.

Следующий отрывок из книги Крейга Уоллса «Весенний ботинок в действии», кажется, именно то, что я ищу, но его основной инструмент ( @SpringApplicationConfiguration ) теперь устарел (и его официально рекомендованная замена- @SpringBootTest — ведет себя не одинаково, по крайней мере, в отношении атрибута classes ):

Although @ContextConfiguration does a great job of loading the Spring application context, it doesn’t load it with the full Spring Boot treatment…SpringApplication not only loads the application context, but also enables logging, the loading of external properties (application.properties or application.yml), and other features of Spring Boot. If you’re using @ContextConfiguration, you won’t get those features. To get those features back in your integration tests, you can swap out @ContextConfiguration for Spring Boot’s @SpringApplicationConfiguration:

 @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes=AddressBookConfiguration.class) public class AddressServiceTests { ... }  

Там он получает «полную обработку весенней загрузки», но добавляет только класс ( @Service ), который он цитирует (не каждый @Component , @Controller , и @Repository его домена).

Как сделать это сегодня, не устарев @SpringApplicationConfiguration ?

Обновить

Первоначально я заявил , что мой (не Крейга Уоллса) пример (а именно @SpringBootTest(classes={SomeServiceImpl.class},webEnvironment=WebEnvironment.NONE) , хотя он загрузил указанный класс, скрыл все основы контекста приложения, который обычно загружается при загрузке Spring. В ходе дальнейших экспериментов я обнаружил, что это утверждение было неточным, поскольку не все, а только некоторые основы скрыты, а именно проверка (реализация API проверки Java). Другими словами, ведение журнала, загрузка внешних свойств и подключение @Value действительно загружены/настроены. Я думаю, что я, должно быть, запутался во всех моих многочисленных перестановках/попытках.

Ответ №1:

После еще нескольких экспериментов я нашел ответ. Я не могу сказать, лучший ли это ответ, но он лаконичен и, безусловно, делает свое дело…

 import org.springframework.boot.autoconfigure.ImportAutoConfiguration; import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;  // automatically configures validation (implementation of Java Validation API) @ImportAutoConfiguration(ValidationAutoConfiguration.class)  // obscures/disables any otherwise-automatic web-environment; // automatically configures logging, loading of external properties, and @Value-plugging; // and, beyond that, adds to application-context only _cited_ classes/configuration-classes @SpringBootTest(classes={SomeServiceImpl.class},webEnvironment=WebEnvironment.NONE)// full context loaded, if unqualified  public class SomeServiceTests { ... }