Всегда ли SpringBoot тест с TestRestTemplate требует аннотации @SpringBootTest - PullRequest
0 голосов
/ 17 февраля 2019

Я тестирую контроллер, используя аннотацию @WebMvcTest и MockMvc, он работает нормально:

@WebMvcTest(MyController.class)
class MyControllerSpec extends Specification {

@Autowired
MockMvc mockMvc;

def "test"() {
   def mockRequest = "something"

   when: "we make call"
   def response = mockMvc.perform(post("/getuser")
            .contentType(MediaType.APPLICATION_JSON)
            .content(mockRequest))
            .andReturn().response

   then: "we get response"
   response.status == OK.value()
   }
}

Я прочитал несколько статей в Интернете, в которых мы можем использовать TestRestTemplate для интеграционного тестирования.Мой вопрос заключается в том, что если я использую TestRestTemplate, должен ли я использовать его с аннотацией @SpringBootTest для теста SpringBoot?Причина, по которой я спрашиваю об этом, состоит в том, что в нашем приложении springBoot есть много контроллеров, а также код уровня сервиса / дао.Похоже, мне нужно создать TestConfigure.class для всех bean-компонентов (даже bean-компонентов для других контроллеров, которые я не тестирую) для целей тестирования, в противном случае я получу сообщение об ошибке:

Unable to start EmbeddedWebApplicationContext 
due to missing EmbeddedServletContainerFactory bean

Myтестовый код с использованием TestRestTemplate:

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, 
                classes = [TestConfigure.class])
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
class  MyControllerSpec extends Specification {

@LocalServerPort
private int port;

@Autowired
TestRestTemplate restTemplate

private String createURLWithPort(String uri) {
    return "http://localhost:" + port + uri;
}

def "Integration Success Senario"() {

    given: ""
    when: "we try to get a user using a rest call"

    def request = new User(name, address)

    String jsonResponse = 
       restTemplate.postForObject(createURLWithPort("/getuser"), 
                                  request, String.class)

    .....
   }
 }

1 Ответ

0 голосов
/ 17 февраля 2019

Ошибка просто говорит вам, что в вашем интеграционном тесте отсутствует контейнер сервлета для запуска тестируемой веб-службы.Вам просто нужно как-то настроить этот контейнер.Вы можете сделать это вручную или разрешить Spring сделать то же самое, что и при использовании @SpringBootApplication или @EnableAutoConfiguration.Так что просто добавьте @EnableAutoConfiguration в свой класс интеграционного теста или создайте конфигурацию теста, объявив статический класс внутри теста, и отметьте пометку в нем.Как предлагается в комментарии, следующее предположение неверно

Похоже, мне нужно создать TestConfigure.class для всех bean-компонентов ...

Вотрабочий пример без каких-либо пользовательских bean-компонентов и где Spring просто возвращает 404 для несуществующего метода:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
class MyControllerSpec extends Specification {
    @LocalServerPort
    private int port

    @Autowired
    TestRestTemplate restTemplate

    def "Integration Success Senario"() {
        given: ""
        def request = new User("name", "address")

        when: "we try to get a user using a rest call"
        def response = restTemplate.postForObject(createURLWithPort("/getuser"), request, Map.class)

        then:
        response.status == 404

    }

    private String createURLWithPort(String uri) {
        return "http://localhost:" + port + uri
    }

    @EnableAutoConfiguration //it configures the servlet container
    @Configuration
    static class TestConfig {

    }
}
...