UnsatisfiedDependencyException в тестовом классе @WebMvcTest - PullRequest
0 голосов
/ 24 апреля 2018

Мои модульные тесты не пройдены после того, как я добавил @Service в контроллер. Проект Spring-boot v 2.0.1.RELEASE. Я потратил много часов, пытаясь найти ответ, но не повезло. Тест работал до того, как я добавил аннотацию @Service, и в моем классе обслуживания есть репозиторий.

Трассировка стека:

2018-04-24 12: 57: 12.487 WARN 940 --- [main] o.s.w.c.s.GenericWebApplicationContext: Обнаружено исключение во время инициализации контекста - отмена попытки обновления: org.springframework.beans.factory.UnsatisfiedDependencyException: Ошибка создания бина с именем fleetController: неудовлетворен зависимость выражается через поле «сервис»; вложенное исключение org.springframework.beans.factory.NoSuchBeanDefinitionException: нет квалифицирующий компонент типа 'uk.co.vw.lead.service.ContactUsService' доступно: ожидается по крайней мере 1 бин, который квалифицируется как autowire кандидат. Аннотации зависимостей: {@ Org.springframework.beans.factory.annotation.Autowired (обязательно = истина)}

Контроллер:

@Slf4j
@RestController
@RequestMapping(value = VERSION, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public class FleetController {
public static final String VERSION = "1.0";

@Autowired
private ContactUsService service;

@InitBinder
public void initBinder(final WebDataBinder webDataBinder) {
    webDataBinder.registerCustomEditor(NatureOfEnquiryEnum.class, new  NatureOfEnquiryEnumConverter());
    webDataBinder.registerCustomEditor(FleetSizeEnum.class, new  FleetSizeEnumConverter());
}

@PostMapping(value = "/fleet/contact-us")
public ResponseEntity contactUs(@Valid ContactUsDTO formDTO) {
    service.createForm(formDTO);
    return new ResponseEntity(HttpStatus.NO_CONTENT);
}

@PostMapping(value = "/fleet/request-demo")
public ResponseEntity requestDemo(@Valid RequestDemoDTO demoDTO) {



    return new ResponseEntity(HttpStatus.NO_CONTENT);
}

Услуги:

@Service
public class ContactUsServiceImpl implements ContactUsService {

@Autowired
private FleetRepository repository;

@Override
public void createForm(ContactUsDTO formDTO) {
    ContactUsForm form = populateContactUsForm(formDTO);
    repository.save(form);
}

}

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

@RunWith(JUnitPlatform.class)
@WebMvcTest(FleetController.class)
@ExtendWith(SpringExtension.class)
public class FleetControllerTest {

private final String CONTACT_US_URL = "/fleet/contact-us";

@Autowired
private MockMvc mockMvc;

@MockBean
private FleetRepository repository;

@Autowired
private ContactUsService service;


@Test
public void contactUsSuccessTest() throws Exception {
    this.mockMvc.perform( post("/" + VERSION + CONTACT_US_URL)
                    .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
                    .param("firstname", "John")
                    .param("lastname", "Doe")
                    .param("company", "Skynet")
                    .param("emailAddress", "john.connor@sky.net")
                    .param("telephone", "020 8759 4294")
                    .param("natureOfEnquiry", "new")
                    .param("comments", "some comments")
                    .param("recaptchaResponse", "success"))
            .andExpect(status().isNoContent());
}

@Test
public void contactUsMissingRequiredFieldsTest() throws Exception {
    this.mockMvc.perform( post("/1.0/fleet/contact-us")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE))
            .andExpect(status().isBadRequest());
}

}

Пожалуйста, помогите, поскольку я понятия не имею, что происходит.

1 Ответ

0 голосов
/ 24 апреля 2018

Тест, классифицированный как @WebMvcTest, - это тесты, в которых только сосредоточены на компонентах Spring MVC: контроллерах.

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

@Autowired
private ContactUsService service;

Так что вы должны посмеяться над этой зависимостью:

@MockBean
private ContactUsService service;

Обратите внимание, что, поскольку FleetController не имеет прямой зависимости от FleetRepository, насмешка над этим компонентом не требуется:

@MockBean
private FleetRepository repository;

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


В качестве альтернативы, если вы хотите смоделировать только некоторые bean-компоненты, а не все, которые не являются контроллерами, не используйте @WebMvcTest и вместо @SpringBootTest, который будет загружать весь контекст.
Затем объявите в тестовом классе класс (ы), который вы хотите смоделировать с помощью @MockBean.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...