MockMvc сохраняет Json с нулевыми полями в тесте RestController

Контекст

Я работаю над небольшим приложением REST в Spring Boot. Я хотел бы выполнить тестовый контроллер (POST.METHOD), который добавляет новый объект в базу данных.

Проблема

Я создаю новую сущность через конструктор и указываю поля в своем объекте. Затем я сохраняю этот объект через MockMvc. И есть проблема, MockMvc сохранил мой объект, но все поля нулевые или ложные. Сервис, который использует контроллер, протестирован и работает корректно

Код

Контроллер:

    @RestController
    public class ParkingMeterController {

    @Autowired
    ParkingMeterService parkingMeterService;

    @PostMapping("parking-meter")
    public ParkingMeter addParkingMeter(){
        ParkingMeter parkingMeter = new ParkingMeter();
        return parkingMeterService.addNewParkingMeter(parkingMeter);
    }

Организация:

    @Entity
    @Component
    @Data
    public class ParkingMeter {

    @Id
    @GeneratedValue
    private long id;
    private boolean occupied = false;
    private Timestamp startTime;
    private Timestamp endTime;

    public ParkingMeter() {
    }

    public ParkingMeter(boolean occupied, Timestamp startTime, Timestamp endTime) {
        this.occupied = occupied;
        this.startTime = startTime;
        this.endTime = endTime;
    }
}

Тестовый класс:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @AutoConfigureMockMvc
    public class ParkingMeterControllerTest {

    @Autowired
    private MockMvc mvc;
    @Autowired
    ParkingMeterService parkingMeterService;

    @Test
    public void shouldAddNewParkingMeter() throws Exception {
        ParkingMeter parkingMeter = new ParkingMeter(true, new Timestamp(0), new Timestamp(5000));
        String json = new Gson().toJson(parkingMeter);
        System.out.println(json);

        mvc.perform(post("/parking-meter/")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(json)
                .accept(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id", is(3)))
                .andExpect(jsonPath("$.startTime", is(new Timestamp(0))));
    }

Результат распечатки системы:

{"id":0,"occupied":true,"startTime":"Jan 1, 1970 1:00:00 AM","endTime":"Jan 1, 1970 1:00:05 AM"}

МокСервлетОтклик:

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {"id":3,"occupied":false,"startTime":null,"endTime":null}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Как вы можете видеть выше. В ответе Mock сервлета мы можем видеть Body с нулевыми и ложными полями, которые отличаются от тех, которые я определил.

Заранее спасибо.


person mastach    schedule 22.10.2017    source источник
comment
хаха я знаю этот код   -  person Kamil Nękanowicz    schedule 24.08.2020


Ответы (1)


Думаю, проблема в том, что вы сериализуете временную метку в формате даты (используя сопоставитель Gson), но десериализуете ее в другом формате (скажем, используя сопоставитель Джексона по умолчанию Spring).

Существует множество способов настроить сериализацию/десериализацию типа данных, но я рекомендую вам установить значение тела json непосредственно как String в формате, который вы ожидаете получить. Например:

String json = "{\"id\":0,\"occupied\":true,\"startTime\":\"0000000000000\",\"endTime\":\"0000000005000\"}"

Такой подход гарантирует, что ваши тесты также будут проверять проблемы с сериализацией/десериализацией!

person Alex Saunin    schedule 22.10.2017
comment
Привет, Алекс. Спасибо за ваш пост. - person mastach; 23.10.2017
comment
Я думаю, что Gson не проблема. Я пытался использовать класс ObjectMapper, но это не помогло. Кроме того, как вы можете видеть в моем посте, есть проблема с логическим полем. Я пытался сохранить объект с занятым полем: true, но объект был сохранен с занятым: false. Однако я закончу свои тесты, определив json вручную, как вы упомянули. - person mastach; 23.10.2017
comment
@mastach Если ваш запрос возвращает неожиданные данные, возможно, проблема связана с вашим parkingMeterService. Из кода кажется, что вы используете настоящий (вместо макета). Поэтому попробуйте проверить, вызывает ли он правильные аргументы метода, соответствующие ожидаемым результатам. - person Alex Saunin; 23.10.2017
comment
ааа это моя ошибка. Ты прав. Мой RestController для ParkingMeter каждый раз создает новый экземпляр ParkingMeter, поэтому он ложный и нулевой (значения полей по умолчанию). Json был в порядке, но контроллер сохранил другой объект (новый). Аааа мой лох. Большое спасибо! - person mastach; 23.10.2017
comment
@mastach Вам удалось? Так ли это, не стесняйтесь закрыть этот вопрос - person Alex Saunin; 24.10.2017
comment
Да, все работает, спасибо. Я думаю, что у меня недостаточно репутации, чтобы закрыть свой вопрос; P - person mastach; 24.10.2017
comment
@mastach Странно. У вас должна быть привилегия принять ответ, будучи его автором. Узнайте, как это сделать здесь - person Alex Saunin; 24.10.2017