【问题标题】:UriComponentsBuilder/MvcComponentsBuilder usage in a Spring Boot Test在 Spring Boot 测试中使用 UriComponentsBuilder/MvcComponentsBuilder
【发布时间】:2020-01-18 23:02:12
【问题描述】:

我已经放了一个非常简单的sample project on GitHub 来重现问题。

主要问题是我有一个 PersonController 有一个 PutMapping 来创建一个新人。为了使用 URL 填充 Location 标头以获取该人,我添加了 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 上使用示例项目时遇到了同样的问题。

【问题讨论】:

    标签: spring-boot spring-mvc spring-boot-test spring-mvc-test


    【解决方案1】:

    您尝试过 MockMvc 吗?以下代码将以处理 HTTP 请求的相同方式调用,因为您使用的是 @WebMvcTest,仅调用 Web 层而不是整个上下文。

    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/guides 参考

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

    【讨论】:

    • 天哪,我怎么没想到,我把所有东西都设置好了:P。感谢您的帮助。
    猜你喜欢
    • 2020-07-21
    • 2014-11-30
    • 1970-01-01
    • 2019-03-07
    • 2019-04-28
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2015-06-14
    相关资源
    最近更新 更多