Cannot send request body to integration test method in Spring Boot JUnit (objectMapper.writeValueAsString Issue)

huangapple go评论89阅读模式
英文:

Cannot send request body to integration test method in Spring Boot JUnit (objectMapper.writeValueAsString Issue)

问题

我有一个处理Spring 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

在控制器的refreshToken方法中,当mockMvc尝试调用该方法时,refreshTokenRequest的值为空,因为我删除了@RequestBody

我应该如何修复这个问题?

英文:

I have a problem to handle with sending request body to integration test in Spring Boot JUnit.
I got 400 Bad Request instead of 200 Ok.

Here is the AdminRefreshTokenRequest shown below

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

@Data
@Builder
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

Here is the refreshToken method shown below

@PostMapping(&quot;/refreshtoken&quot;)
    public ResponseEntity&lt;?&gt; refreshToken(@RequestBody AdminRefreshTokenRequest refreshTokenRequest) {
  .....
}

Here is the relevant part of integration test method shown below

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

AdminRefreshTokenRequest refreshTokenRequest = AdminRefreshTokenRequest.builder()
                .refreshToken(&quot;RefreshToken&quot;)
                .build();

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

I get this issue shown below

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

java.lang.AssertionError: Status expected:&lt;200&gt; but was:&lt;400&gt;
Expected :200
Actual   :400

The value assigning to refreshTokenRequest in refreshToken method of controller is null when mockMvc try to call the method after I delete @RequestBody.

How can I fix it?

答案1

得分: 1

以下是翻译好的部分:

这是下面显示的解决方案。

删除了@Builder,该注解用于多个变量,我定义了@NoArgsConstructor@AllArgsConstructor。接下来,问题消失了。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}
英文:

Here is the solution shown below.

After deleting @Builder which is used for more than one variable, I defined both @NoArgsConstructor and @AllArgsConstructor. Next, the issue disappeared.

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

答案2

得分: 0

问题在于你的后端无法初始化请求体。默认情况下,框架会执行以下操作:

  1. 创建请求体的实例;
  2. 填充变量;
  3. 最终使用构建好的请求体进入映射的方法。

在第一步中,框架会调用你的请求体类的空构造函数,如果该构造函数缺失,将会返回 400 错误代码。

要解决这个问题,你可以简单地用 @NoArgsConstructor 替换 @Builder 注解,放在你的 AdminRefreshTokenRequest 类上。最终的请求体类应该如下所示:

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

@Data
@NoArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

这样应该能解决问题,希望能帮到你。

英文:

The problem is that your back-end is not able to initialize the request body.
By default what the framework does is to:

  1. it creates the instance of the request body;
  2. then it is going to populate variables;
  3. finally it goes into the mapped method with the builded body.

In the first step the framework is going to call the empty constructor of your body class, so if it is missing it is going to reply with a 400 error code.

To fix the problem you can simply replace the @Builder annotation with the @NoArgsConstructor in your AdminRefreshTokenRequest class.
The final body class should look like the following:

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

@Data
@NoArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

This should fix the problem, hope it helps.

huangapple
  • 本文由 发表于 2023年3月31日 21:12:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75898955.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定