Nano Hash - криптовалюты, майнинг, программирование

Есть ли способ включить компонент Spring в WebMvcTest

Данные классы производственного кода:

@RestController
@RequiredArgsConstructor
public class MyController {

    private final MyValidator validator;

    // annotations relating to request mapping excluded for brevity 
    public void test(@Valid @RequestBody final MyParams params) {
        // do stuff
    }

    @InitBinder
    @SuppressWarnings("unused")
    protected void initBinder(final WebDataBinder binder) {
        binder.setValidator(validator);
    }
}

и

@Component
@RequiredArgsConstructor
public class MyValidator implements Validator {

    ...

    @Override
    public void validate(final Object target, final Errors errors) {
        // custom validation
    }
}

и, наконец, тестовый код:

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTest {
    // tests
}

Я обнаружил ошибку:

NoSuchBeanDefinitionException: нет подходящего bean-компонента типа MyValidator: ожидается как минимум 1 bean-компонент, который квалифицируется как кандидат autowire. Аннотации зависимостей: {}

Думаю, ошибка вполне справедлива. Я аннотировал тест как WebMvcTest, который, как мне кажется, исключил @Component beans. Это сделано намеренно и желательно (с точки зрения того, что я хочу протестировать только «веб-слой», а не весь контекст - так уж случилось, что мне нужен компонент, который связан / используется только в контроллерах)

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

Моя среда - java version "10.0.2" 2018-07-17, весенняя загрузка 1.5.16.RELEASE.


Ответы:


1

Есть два способа протестировать веб-слой

первый.

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyControllerTest {
  @Autowired
  private MyController myController;
}

Аннотация @SpringBootTest сообщает Spring Boot искать основной класс конфигурации (например, с @SpringBootApplication) и использовать его для запуска контекста приложения Spring.

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

Во-вторых, если вы хотите использовать @WebMvcTest (MyController.class)

@RunWith(SpringRunner.class)
@WebMvcTest(MyController.class)
public class MyControllerTest {

  @MockBean
  private MyValidator validator;

}

Но этот валидатор - подделка, поэтому его придется настраивать для тестирования.

См. Эту ссылку для получения дополнительных сведений. https://spring.io/guides/gs/testing-web/

17.10.2018
  • Верно ли сказать, что первый подход, описанный выше, скорее всего (возможно, в зависимости от другой конфигурации, найденной в классе SpringBootApplication), запустит весь контекст Spring (все службы, репозитории, компоненты и т. Д.). Второй подход - это то, что я уже делаю: я мог бы использовать поддельный валидатор и написать отдельные модульные тесты для логики валидатора, чтобы охватить реализацию. Я также поэкспериментирую с WebMvcConfigurerAdapter определением beans - поскольку я думаю, что эти beans тогда будут применяться в контексте. 17.10.2018

  • 2

    Я не могу рекомендовать это как стандартную практику, но если вам действительно нужен экземпляр зависимости в ваших тестах Web MVC (например, в устаревшем коде), вы можете добавить их в контекст Spring, используя _ 1_ аннотация.

    Реальные методы этого класса будут вызываться во время теста, и вы можете проверить их при необходимости аналогично bean-компонентам, помеченным @MockBean

    @RunWith(SpringRunner.class)
    @WebMvcTest(MyController.class)
    public class MyControllerTest {
    
        @SpyBean
        private MyValidator validator
    }
    
    26.08.2019
  • Это прекрасно сработало! 18.06.2021

  • 3

    Есть два способа решить эту проблему.

    1. Использование @SpringBootTest и @AutoConfigureMvc вместо @RunWith (SpringRunner.class) и @WebMvcTest.

      @SpringBootTest
      @AutoConfigureMvc
      public class MyControllerTest {
      
      }
      
    2. Создание класса @TestConfiguration, который внедряет bean-компонент MyValidator как:

          @RunWith(SpringRunner.class)
          @WebMvcTest(MyController.class)
          public class MyControllerTest {
             @TestConfiguration
             static class TestConfig {
                @Bean
                MyValidator getMyValidator(){
                    return new MyValidator();
                }
             }
             // tests
          }
      

      Подробнее об этом можно прочитать здесь: https://mkyong.com/spring-boot/spring-boot-how-to-init-a-bean-for-testing/

    10.05.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..