有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何做一个简单的RESTAPI控制器测试?

因此,我试图对我的控制器的post方法进行测试,但我不断发现,其他人对我或他们的post方法不进行操作的测试要高级得多

我的发帖方法

@Autowired
PartyLeaderService partyleaderService;

@PostMapping("/")
public void add(@RequestBody PartyLeaderDto partyLeaderDto){
    partyLeaderService.savePartyLeader(partyLeaderDto);
}

正如你所看到的,它相当简单,但我似乎仍然无法让它正常工作。 我试过这个方法:

@Test
public void testPostExample() {
    PartyLeaderDto partyLeaderDto = new PartyLeaderDto(1, "arun", "link");

    partyLeaderController.add(partyLeaderDto);
    Mockito.verify(partyLeaderController).add(partyLeaderDto);
}

但是SonarQube说测试中还没有包括这种方法,所以我的测试肯定是错误的

我的DTO

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class PartyLeaderDto {
    private Integer id;
    private String name;
    private String apperance;
}

有人能帮我吗?因为我觉得答案很简单,但我似乎找不到


共 (3) 个答案

  1. # 1 楼答案

    您在这里所做的实际上是通过验证存根调用进行单元测试

    您可以通过使用Mockito的when(..)模拟行为进行单元测试。然后(…)然后使用断言来断言结果

    或 您可以按照本文使用MockMvc一步一步地进行集成测试- https://www.baeldung.com/integration-testing-in-spring

  2. # 2 楼答案

    单元测试的问题在于,您正在验证对非模拟对象的调用

    Mockito.verify(partyLeaderController).add(partyLeaderDto);
    

    partyLeaderController不是模拟的,因为这是您目前要测试的。 你应该模拟和验证的是PartyService

      @Test
      public void testPostExample() {
        PartyService partyService = mock(PartyService.class);
        PartyLeaderController controller = new PartyLeaderController(partyService);
        PartyLeaderDto partyLeaderDto = new PartyLeaderDto(1, "arun", "link");
    
        controller.add(partyLeaderDto);
        
        Mockito.verify(partyService).saveParty(partyLeaderDto);
      }
    

    然而,这并不是一种很好的测试web层的方法,因为您应该在测试中考虑的不仅仅是是否调用了PartyService,还包括您在给定路径中公开了一个端点,这个端点需要POST方法,它需要一个对象(可能是json?)它会返回一个状态码(可能还有一个响应对象?)

    一种简单、类似单元测试的方法是使用MockMvc

      @Test
      public void testPostExample() {
        PartyService partyService = mock(PartyService.class);
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PartyLeaderController(partyService)).build();
        PartyLeaderDto partyLeaderDto = new PartyLeaderDto(1, "arun", "link");
    
        mockMvc.perform(
            post("/party")
                .contentType(MediaType.APPLICATION_JSON)
                .content(new ObjectMapper().writeValueAsString(partyLeaderDto))
        ).andExpect(status().isOk());
        verify(partyService).saveParty(partyLeaderDto);
      }
    
  3. # 3 楼答案

    在Yayotron的帮助下,我找到了答案。 代码如下:

    @Test
    @WithMockUser("Test User")
    public void testPostParty() throws Exception {
        PartyLeaderService partyLeaderService = mock(PartyLeaderService.class);
        MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PartyLeaderController(partyLeaderService)).build();
        PartyLeaderDto partyLeaderDto = new PartyLeaderDto(1, "arun", "link");
    
        mockMvc.perform(
                MockMvcRequestBuilders.post("http://localhost:8080/partyleaders/")
                        .contentType(MediaType.APPLICATION_JSON)
                        .content(new ObjectMapper().writeValueAsString(partyLeaderDto))
        ).andExpect(status().isOk());
        Mockito.verify(partyLeaderService).savePartyLeader(ArgumentMatchers.refEq(partyLeaderDto));
    }
    

    非常感谢你的帮助