java 无法将请求正文发送到Sping Boot JUnit中的集成测试方法(objectMapper.writeValueAsString Issue)

baubqpgj  于 2023-04-04  发布在  Java
关注(0)|答案(2)|浏览(143)

我在Sping Boot JUnit中发送请求体到集成测试时遇到了一个问题。我得到了400个Bad Request而不是200个OK。
下面是AdminRefreshTokenRequest

import jakarta.validation.constraints.NotBlank;
import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

下面是refreshToken方法

@PostMapping("/refreshtoken")
    public ResponseEntity<?> refreshToken(@RequestBody AdminRefreshTokenRequest refreshTokenRequest) {
  .....
}

下面是集成测试方法的相关部分

@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;

AdminRefreshTokenRequest refreshTokenRequest = AdminRefreshTokenRequest.builder()
                .refreshToken("RefreshToken")
                .build();

mockMvc.perform(post(ADMIN_CONTROLLER_BASEURL + "/refreshtoken")
                        .contentType("application/json")
                        .content(objectMapper.writeValueAsString(refreshTokenRequest)))
                .andDo(print())
                .andExpect(status().isOk())

我得到这个问题如下所示

MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = [Content-Type:"application/problem+json"]
     Content type = application/problem+json
             Body = {"type":"about:blank","title":"Bad Request","status":400,"detail":"Failed to read request","instance":"/api/v1/refreshtoken"}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status expected:<200> but was:<400>
Expected :200
Actual   :400

在我删除@RequestBody之后,当mockMvc尝试调用控制器的refreshToken方法时,分配给refreshTokenRequest的值为null。
我该怎么修呢?

ou6hu8tu

ou6hu8tu1#

问题是你的后端无法初始化请求体。默认情况下,框架所做的是:
1.它创建请求体的示例;
1.然后填充变量
1.最后,它进入与构建体的Map方法。
在第一步中,框架将调用body类的空构造函数,因此如果缺少它,它将返回400错误代码。
要解决这个问题,您只需在AdminRefreshTokenRequest类中将**@Builderannotation替换为@NoArgsConstructor**即可。最终的body类应该如下所示:

import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

这应该可以解决问题,希望有帮助。

ttcibm8c

ttcibm8c2#

下面是解决方案。
在删除用于多个变量的@Builder之后,我定义了@NoArgsConstructor@AllArgsConstructor。接下来,问题消失了。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

相关问题