JUnit 5单元测试的Get和Post方法

时间:2020-05-21 13:40:49

标签: spring-boot unit-testing spring-mvc junit5 spring-restcontroller

我是Spring Boot和Junit测试的新手。我在测试Rest Api的Get and Post方法时遇到问题。许多教程在线指南都介绍了在JUnit测试中使用嘲笑Mvc。但是那些仍然对JUnit 5有效。

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = RegisterRestController.class)
class RegisterRestControllerTest {
  @Autowired
  private MockMvc mockMvc;

  @Autowired
  private ObjectMapper objectMapper;

  @MockBean
  private RegisterUseCase registerUseCase;

  @Test
  void whenValidInput_thenReturns200() throws Exception {
    mockMvc.perform(...);
  }

}

但是,我读过一篇文章,从SpringBoot 2.1开始,您不需要包含@ExtendWith扩展。 自从Junit 5和spring boot都更新了以前版本的许多更改之后,就很难分析哪些在线可用代码对于测试是正确的。 我无法使用MockMvc.perform()。andExpect(status()。isOk())。

mockMvc.perform(post("/forums/{forumId}/register", 42L)
    .contentType("application/json")
    .param("sendWelcomeMail", "true")
    .content(objectMapper.writeValueAsString(user)))
    .andExpect(status().isOk());

测试Get和post方法的正确用法是什么。然后测试剩余动词是在单元测试还是在集成测试下?

也为我提供了很好的参考,以使用Spring Boot检查Junit 5的更新功能(对我而言JUnit 5文档没有帮助)。

1 个答案:

答案 0 :(得分:0)

您可以在单元测试中使用MockMvcRequestBuilders。这是一个带有post的示例。


@ExtendWith(SpringExtension.class)
@WebMvcTest(RegisterRestController.class)
@AutoConfigureMockMvc(addFilters = false) //for disabling secruity, remove if not needed
class RegisterRestControllerTest {

    @MockBean
    private MyService myService;

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void someTest() {
        // mock post of new User
        when(myService.createPojo(User.class)))
                .thenAnswer((Answer<User>) 
                     invocationOnMock -> invocationOnMock.getArgument(0, User.class));

        // test post request with data
        mockMvc.perform(MockMvcRequestBuilders
                .post("/forums/{forumId}/register", 42L)
                .contentType("application/json")
                .param("sendWelcomeMail", "true")
                .content(objectMapper.writeValueAsString(user)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("some name"));
    }

类似地,您可以测试GET,PUT和DELETE。希望可以帮助您测试控制器。

要回答单元与集成测试部分:在这种情况下,您正在测试一个单元,即控制器。处理事务和所有其他层的服务被模拟,例如在我的示例代码中使用了模拟。

对于集成测试,您不会使用任何模拟。并且您将拥有一个真实的数据库或至少一个像h2这样的“假数据库”。