0

Я портированию приложения через дорогу от JDBC/REST для spring-data-rest и мой один и только модульного тестирования с завершается с ошибкойне удалось запустить пружинными данных остальное модульное тестирование, RepositoryRestResource не доступен @Autowire

NoSuchBeanDefinitionException: 
    No qualifying bean of type 'com.xxx.repository.ForecastRepository' available 

Приложение было ретро-оснащено spring-boot только ранее, и теперь я пытаюсь установить новый слой на место с помощью spring-data-rest поверх spring-data-jpa.

Я пытаюсь выработать правильный Java-конфигурацию в соответствии с

Custom Test Slice with Spring Boot 1.4

, но я должен был отойти от идиоматического подхода, поскольку

  1. @WebMvcTest аннотации не подавляет защитный модуль, который вызывает сбой теста
  2. @MockMvcAutoConfiguration не удалось из-за отсутствующих зависимостей, если не укажу @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) (см here)
  3. @WebMvcTest и @SpringBootTest являются взаимоисключающими, так как они оба указать @BootstrapWith и не могут работать вместе

Так это ближайший я получил, но весна не может найти мой @RepositoryRestResource репозиторий:

Repository

@RepositoryRestResource(collectionResourceRel = "forecasts", path = "forecasts") 
public interface ForecastRepository extends CrudRepository<ForecastExEncoded, 
     Long> { 

JUnit Test

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, 
     classes = {TestRestConfiguration.class}) 
public class ForecastRestTests { 

    @Autowired 
    private MockMvc mockMvc; 

    @Autowired 
    private ForecastRepository forecastRepository; 

    @Before 
    public void deleteAllBeforeTests() throws Exception { 
     forecastRepository.deleteAll(); 
    } 

    @Test 
    public void shouldReturnRepositoryIndex() throws Exception { 

     mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()).andExpect(
       jsonPath("$._links.forecasts").exists()); 
    } 

} 

Конфигурация

@OverrideAutoConfiguration(enabled = false) 
@ImportAutoConfiguration(value = { 
     RepositoryRestMvcAutoConfiguration.class, 
     HttpMessageConvertersAutoConfiguration.class, 
     WebMvcAutoConfiguration.class, 
     MockMvcAutoConfiguration.class, 
     MockMvcSecurityAutoConfiguration.class 
}) 
@Import({PropertySpringConfig.class}) 
public class TestRestConfiguration {} 

Также пробовал ...

Я пытался настроить модульного тестирования с только @WebMvcTest и это @ComponentScan ниже от How to exclude AutoConfiguration from Spring Boot), в попытке упростить все, однако excludeFilters не имел ef fect.

@ComponentScan(
     basePackages="com.xxx", 
     excludeFilters = { 
       @ComponentScan.Filter(type = ASSIGNABLE_TYPE, 
         value = { 
           SpringBootWebApplication.class, 
           JpaDataConfiguration.class, 
           SecurityConfig.class 
         }) 
     }) 

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

Я могу видеть в протоколе, что загружается RepositoryRestConfiguration, но, очевидно, он не снабжается нужной информацией, и я не могу разобраться, как это делается, после поиска в Google и добавлениях к документам Spring и API. Я думаю, что, должно быть, я прочитал каждый соответствующий вопрос здесь.

Обновление 2016-11-16 10:00

Одна вещь, которую я вижу в журналах, которые меня волнуют это:

Performing dependency injection for test context [[email protected] [snip...] 
classes = '{class com.xxx.TestRestConfiguration, 
    class com.xxx.TestRestConfiguration}', 

т.е. контекст перечисляет класс конфигурации дважды. Я указал класс конфигурации (только один раз) в аннотации @SpringBootTest#classes. Но если я оставлю #classes из аннотации, Spring Boot найдет и вытащит всю конфигурацию через класс @SpringBootApplication.

Так что это намек на то, что я указываю конфигурацию в другом месте? Как еще я это сделаю?

ответ

1

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

Custom Test Slice with Spring Boot 1.4 выглядел многообещающе, но я ничего не мог с ним поделать.

Идя снова и снова

Accessing JPA Data with REST

я понял, что я должен был включать в себя установку JPA, потому что spring-data-rest не использовать их напрямую - нет шансов высмеивать их или запускать модульные тесты без встроенной базы данных.

По крайней мере, насколько я понимаю. Может быть, их можно издеваться над ними и иметь spring-data-rest бегать по макетам против тестовых данных, но я думаю, spring-data-rest и spring-data, вероятно, слишком тесно связаны.

Так что тестирование интеграции должно быть.

В исходном коде Spring снабженных статей выше

gs-accessing-data-rest/ApplicationTests.java

лесозаготовительные показывает Spring Загрузочного втягивая всю конфигурацию для контекста приложения.

Так что мой SpringBootApplication класс избегали и модуль безопасности не загружен, я настроить свои тесты, как это:

@RunWith(SpringRunner.class) 
@SpringBootTest 
@ContextConfiguration(classes = { 
     JpaDataConfiguration.class, 
     TestJpaConfiguration.class, 
     TestRestConfiguration.class, 
     PropertySpringConfig.class}) 
public class ForecastRestTests { 

    @SuppressWarnings("SpringJavaAutowiringInspection") 
    @Autowired 
    private MockMvc mockMvc; 

    @Autowired 
    private ForecastRepository forecastRepository; 

    @Before 
    public void deleteAllBeforeTests() throws Exception { 
     forecastRepository.deleteAll(); 
    } 

    @Test 
    public void shouldReturnRepositoryIndex() throws Exception { 

     mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()).andExpect(
       jsonPath("$._links.forecasts").exists()); 
    } 

} 

с этими классами конфигурации:

@Configuration 
@EnableJpaRepositories(basePackages = {"com.bp.gis.tardis.repository"}) 
@EntityScan(basePackages = {"com.bp.gis.tardis.type"}) 
public class JpaDataConfiguration { 

и

@Configuration 
@OverrideAutoConfiguration(enabled = false) 
@ImportAutoConfiguration(value = { 
     CacheAutoConfiguration.class, 
     JpaRepositoriesAutoConfiguration.class, 
     DataSourceAutoConfiguration.class, 
     DataSourceTransactionManagerAutoConfiguration.class, 
     HibernateJpaAutoConfiguration.class, 
     TransactionAutoConfiguration.class, 
     TestDatabaseAutoConfiguration.class, 
     TestEntityManagerAutoConfiguration.class }) 
public class TestJpaConfiguration {} 

и

@Configuration 
@OverrideAutoConfiguration(enabled = false) 
@ImportAutoConfiguration(value = { 
     RepositoryRestMvcAutoConfiguration.class, 
     HttpMessageConvertersAutoConfiguration.class, 
     WebMvcAutoConfiguration.class, 
     MockMvcAutoConfiguration.class, 
     MockMvcSecurityAutoConfiguration.class 
}) 
public class TestRestConfiguration {} 

поэтому TL; DR резюме: использовать @ContextConfiguration указать файлы конфигурации, которые определяют @OverrideAutoConfiguration и @ImportAutoConfiguration

 Смежные вопросы

  • Нет связанных вопросов^_^