Использование UriComponentsBuilder / MvcComponentsBuilder в тесте Spring Boot - PullRequest
0 голосов
/ 19 января 2020

Я поместил очень простой пример проекта на GitHub , чтобы воспроизвести проблему.

Основная проблема заключается в том, что у меня есть PersonController, для создания которого PutMapping новый человек. Чтобы заполнить заголовок Location URL-адресом для извлечения этого человека, я добавляю UriComponentsBuilder в качестве параметра для этого PutMapping, как вы можете видеть здесь:

  @PostMapping
  public ResponseEntity<Person> add(@RequestBody final PersonForCreate personForCreate, UriComponentsBuilder uriComponentsBuilder) {
    Person newPerson = new Person(this.people.size() + 1, personForCreate.getFirstName(), personForCreate.getLastName());
    this.people.add(newPerson);

    // create the URI for the "Location" header
    MvcUriComponentsBuilder.MethodArgumentBuilder methodArgumentBuilder = MvcUriComponentsBuilder.fromMappingName(uriComponentsBuilder, "getById");
    methodArgumentBuilder.arg(0, newPerson.getId());
    URI uri = URI.create(methodArgumentBuilder.build());

    return ResponseEntity.created(uri).body(newPerson);
  }

Это прекрасно работает, когда запустить проект. Но при запуске теста это приводит к IllegalArgumentException No WebApplicationContext. Ошибка возникает из-за вызова MvcUriComponentsBuilder.fromMappingName, но я понятия не имею, почему.

Мой тест выглядит следующим образом:

@ExtendWith(SpringExtension.class)
@WebMvcTest
class PersonControllerTest {

  @Autowired
  private PersonController personController;

  @Test
  void add() {
    this.personController.add(new PersonForCreate("Charles", "Darwin"), UriComponentsBuilder.newInstance());
  }
}

Я не уверен, что прохождение UriComponentsBuilder.newInstance() правильно , но я пробовал с другими значениями и не заметил никакой разницы.

К вашему сведению, пример проекта использует Spring Boot 2.2.3 и JUnit 5, но у меня та же проблема с использованием примера проекта на JUnit 4.

1 Ответ

1 голос
/ 19 января 2020

Вы пробовали Mock Mvc? Следующий код будет вызываться так же, как обрабатывается HTTP-запрос, так как вы используете @WebMvcTest, вызывается только веб-слой, а не весь контекст.

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

@WebMvcTest
class PersonControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void add() throws Exception {
        //this.personController.add(new PersonForCreate("Charles", "Darwin"), uriComponentsBuilder);
        this.mockMvc.perform(MockMvcRequestBuilders.post("/person")
                .content("{\"firstName\": \"Charles\",\"lastName\": \"Darwin\"}").contentType(MediaType.APPLICATION_JSON))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isCreated())
                .andExpect(MockMvcResultMatchers.content().string("{\"id\":4,\"firstName\":\"Charles\",\"lastName\":\"Darwin\"}"));
    }
}

Spring.io / справочник гидов

https://spring.io/guides/gs/testing-web/

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