Не удается отправить тело запроса методу интеграционного тестирования в Spring Boot JUnit (проблема objectMapper.writeValueAsString)

У меня возникла проблема с отправкой тела запроса на интеграционный тест в 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

Значение, присвоенное refreshTokenRequest в методе refreshToken контроллера, равно нулю, когда mockMvc пытается вызвать метод после удаления @RequestBody.

Как я могу это исправить?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
170
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема в том, что ваш сервер не может инициализировать тело запроса. По умолчанию фреймворк делает следующее:

  1. он создает экземпляр тела запроса;
  2. затем он собирается заполнить переменные;
  3. наконец, он переходит в метод сопоставления с построенным телом.

На первом этапе фреймворк вызовет пустой конструктор вашего класса тела, поэтому, если он отсутствует, он ответит кодом ошибки 400.

Чтобы решить эту проблему, вы можете просто заменить аннотацию @Builder на @NoArgsConstructor в своем классе AdminRefreshTokenRequest. Окончательный класс тела должен выглядеть следующим образом:

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

@Data
@NoArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

Это должно решить проблему, надеюсь, это поможет.

Это не помогло мне решить проблему.

S.N 31.03.2023 15:42

objectMapper.writeValueAsString используется более чем для одного поля, но AdminRefreshTokenRequest имеет только одно поле.

S.N 31.03.2023 16:57
Ответ принят как подходящий

Вот решение, показанное ниже.

После удаления @Builder, который используется более чем для одной переменной, я определил и @NoArgsConstructor, и @AllArgsConstructor. Далее проблема исчезла.

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AdminRefreshTokenRequest {

    @NotBlank
    private String refreshToken;
}

Другие вопросы по теме