Java -单元测试中响应JSON的输出不正确

uqzxnwby  于 2023-04-28  发布在  Java
关注(0)|答案(1)|浏览(121)

我正在测试我的depositUserBalance端点控制器,这只是一个简单的测试,但我不知道为什么它没有得到正确的响应JSON相比,在我的REST API返回。

// My Controller
@PutMapping("/api/deposit")
public ResponseEntity<UserAmountDTO> depositUserBalance(HttpServletRequest request,
                @RequestBody UserAmountDTO userAmountDTO) {
        Integer userId = (Integer) request.getAttribute("userId");
        userAmountDTO = userService.updateUserBalance(userId, userAmountDTO);
        return new ResponseEntity<>(userAmountDTO, HttpStatus.OK);
}
// My UserAmountDTO Data Transfer Object
@Getter
@Setter
@AllArgsConstructor
public class UserAmountDTO {
    
    @JsonProperty(access = Access.WRITE_ONLY)
    public double amount;

    @JsonProperty(access = Access.READ_ONLY)
    public double balance;

}
@Test
public void Test_DepositUserBalance() throws Exception {
    // Arrange
    UserAmountDTO userAmountDTO = new UserAmountDTO(2000.0, 3000.0);
    HttpServletRequest request = mock(HttpServletRequest.class);
    when(request.getAttribute("userId")).thenReturn(1);
    when(userService.updateUserBalance(1, userAmountDTO)).thenReturn(userAmountDTO);
    String requestBody = objectMapper.writeValueAsString(userAmountDTO);
    System.out.println("requestBody: " + requestBody);

    // Act
    MvcResult mvcResult = mockMvc.perform(put(DEPOSIT_PATH)
            .contentType(MediaType.APPLICATION_JSON)
            .content(requestBody).with(requestBuilder -> {
                requestBuilder.setAttribute("userId", 1);
                return requestBuilder;
            }))
            .andExpect(status().isOk())
            .andReturn();

    // Assert
    int status = mvcResult.getResponse().getStatus();
    String content = mvcResult.getResponse().getContentAsString();
    String expectedJson = String.format("{\"balance\":%.1f}", 3000.0);
    assertEquals(HttpStatus.OK.value(), status);
    assertEquals(expectedJson, content);
}

在我的单元测试中,requestBody在这里返回为balance requestBody: {"balance":3000.0},而它应该是amount,因为我将@JsonProperty(acccess = Access.WRITE_ONLY)设置为amount。
测试的误差为org.opentest4j.AssertionFailedError: expected: [{"balance":3000.0}] but was: []。为什么它是一个空字符串?当我在Postman上的REST API中尝试它时,它实际上返回了我这个JSON余额。再加上我添加了@JsonProperty(acccess = Access.READ_ONLY)来平衡。

ar7v8xwq

ar7v8xwq1#

更新RESTCONTROLLER上的单元测试后请求

我设法解决了这个错误,总而言之,这是因为我向模拟的服务传递了一个对象,一个不同的内存地址。简单地说,when(userService.updateUserBalance(1, userAmountDTO)).thenReturn(userAmountDTO);,这是模拟userService的合适方法。updateUserBalance方法。

**但是,**在@Test中,userAmountDTO内存地址可能类似于@21835tj3。在我的控制器userAmountDTO = userService.updateUserBalance(userId, userAmountDTO);中,传递到userService.updateUserBalance方法中的userAmountDTO的内存地址可能不同,如@21943jf3,这就是为什么它不匹配单元测试中的模拟服务参数。具有相同字段和值的对象并不意味着它们共享相同的引用,因此模拟的方法没有返回预期的值。
修复方法

使用ArgumentMatchers.any() Mockito匹配UserAmountDTO类的任何对象。因此,将单元测试中的模拟方法更改为when(userService.updateUserBalance(eq(1), ArgumentMatchers.any(UserAmountDTO))).thenReturn(userAmountDTO);
这通常发生在POST请求中,因为我们传入了一个反序列化的JSON对象。还要感谢@JorgeCampos对调试过程的支持。

相关问题