0

The Context

I am working on small REST application in Spring Boot. I would like to perform test Controller (POST.METHOD) which add new object to database.

The Problem

I create new entity through constructor and I specify fields in my object. Then I save this object through MockMvc. And there is a problem, MockMvc saved my object, but all fields are null or false. Service which controller uses is tested and works properly

The Code

Controller:

    @RestController
    public class ParkingMeterController {

    @Autowired
    ParkingMeterService parkingMeterService;

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

Entity:

    @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;
    }
}

Test class:

    @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))));
    }

System out print result:

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

MockServletResponse:

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 = []

As you can see above. In Mock servlet resposne we can see Body with null and false fields which are different from those I have defined.

Thanks in advance.

mastach
  • 23
  • 5

1 Answers1

1

Guess, the problem is that you're serializing timestamp in a date format (using Gson mapper) but deserialize it in the other format (say using Spring default Jackson mapper).

There're bunch of ways how to setup data type serialization/deserialization, but I do recommend you to set json body value directly as a String in a format that you're expecting to receive. For ex:

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

This kind of approach will guarantee that your tests will check serialization/deserialization issues too!

Alex Saunin
  • 976
  • 1
  • 8
  • 15
  • Hello Alex. Thanks for your post. – mastach Oct 23 '17 at 15:10
  • I think that Gson is not a problem. I tried to use ObjectMapper class but it did not help. Moreover as you can see in my post there is also problem with boolean field. I was trying to save object with field occupied: true, but object was saved with occupied: false. However, I will finish my tests with defining json "manually" as you mentioned. – mastach Oct 23 '17 at 15:17
  • @mastach If your request returns unexpected data than there might be an issue with your `parkingMeterService`. From the code it seems that you're using a real one (instead of mock). So try to check if is calling with a correct method arguments corresponding the expected results. – Alex Saunin Oct 23 '17 at 15:37
  • ahh it is my mistake. You are right. My RestController for ParkingMeter creates every time new instance of ParkingMeter that is why it is false and null (default values of fields). Json was ok, but controller saved other object (new one). Ahhh my goof. Thanks a lot! – mastach Oct 23 '17 at 16:08
  • @mastach Were you succeeded? Is so, feel free to close this question – Alex Saunin Oct 24 '17 at 07:25
  • Yes, everything works fine, thanks. I think I don't have enough reputation to close my question ;P – mastach Oct 24 '17 at 16:26
  • @mastach That's strange. You should have a privilege to accept an answer being it's author. See how to do it [here](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Alex Saunin Oct 24 '17 at 19:40