NUnit 5 Spring MVC test NoSuchBeanDefinitionException для автоматической зависимости в подмодуле - PullRequest
0 голосов
/ 26 февраля 2020

У меня есть проект с двумя подмодулями; один - уровень доступа к данным, другой - сервис API. Модуль доступа к данным использует JOOQ и автосвязанный DSLContext в классе обслуживания. Также я использую JUnit 5 и Spring Boot 2.2.4.

Класс QueryService в модуле доступа к данным имеет член типа @Autowired private DSLContext dsl;

Тестовый класс настроен как это:

@SpringBootTest
public class MyServiceTests {

  @Autowired
  QueryService service;

  @Autowired
  private DSLContext dsl;

  @Test
  public void TestDoSomething() throws Exception {
    service.selectBusinessEntityRelatedByBusinessEntity("C00001234", mockAuth);
  }
}

Тесты в этом модуле работают правильно. Конфигурация читается из application.yaml, и autowire внедряет либо реальные сервисы, либо макет в мой QueryService и локальный dsl.

Служба API - это отдельная история. Если я использую аннотацию @SpringBootTest без MVC, я могу успешно получить тесты для внедрения локального DSLContext с конфигурацией из application.yaml. Настройка теста похожа на эту:

@SpringBootTest
public class CustomersControllerTests {

  @Autowired
  private Gson gson;

  @Autowired
  DSLContext dsl;

  @Test
  public void addCustomerTest() {
  }

Мне нужно использовать @WebMvcTest, чтобы инициализировать Mock Mvc, но переключение на @WebMvcTest приводит к сбою внедрения в классе обслуживания, реализованном в данных. модуль доступа. Инъекция не может найти bean-компонент DSLContext в классе обслуживания запросов. Я настроил тест следующим образом:

@WebMvcTest
public class CustomersControllerTests {

  @Autowired
  private MockMvc mockMvc;

  @Autowired
  private Gson gson;

  private static final String testSub = "329e6764-3809-4e47-ac48-a52881045787";

  @Test
  public void addCustomerTest() {

    var newCustomer = new Customer().firstName("John").lastName("Doe");
    mockMvc.perform(post("/customers").content(gson.toJson(newCustomer)).contentType(MediaType.APPLICATION_JSON)
        .with(jwt().jwt(jwt -> jwt.claim("sub", testSub)))).andExpect(status().isNotImplemented());
  }

Это фактическая ошибка:

2020-02-25 18:14:33.655  WARN 10776 --- [           main] o.s.w.c.s.GenericWebApplicationContext   : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customersController': Unsatisfied dependency expressed through field '_customersService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customersService': Unsatisfied dependency expressed through field '_queryService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'queryService': Unsatisfied dependency expressed through field '_dsl'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.jooq.DSLContext' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Итак, я знаю, что конфигурация тестового приложения правильная, потому что она работает, когда не используется MVC аннотация. Кроме того, я могу создать DSLContext в тестах проекта API и фактически запустить службу API вне теста.

Итак, почему нельзя найти DSLContext при использовании тестовой установки MVC?

1 Ответ

1 голос
/ 28 февраля 2020

Это может быть связано с тем, что @WebMvcTest полностью отключает автоконфигурацию Spring Boot и сканирует только в @Controllers и нескольких других выбранных классах, которые вам нужны для ваших ..well ... MVC тестов ..

В документации Spring рекомендуется сделать это в вашем случае:

Если вы хотите загрузить полную конфигурацию приложения и использовать Mock MVC, вам следует рассмотреть @SpringBootTest в сочетании с @ AutoConfigureMock Mvc, а не эта аннотация.

...