簡體   English   中英

spring 中的 POST 方法測試。 代碼 400 而不是 201

[英]POST method test in spring. Code 400 instead of 201

我正在創建一個可以創建汽車 object 的應用程序。 汽車 class 沒有設置器和吸氣器:

package github.KarolXX.demo.model;


import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;

@Entity
@Table(name = "cars")
public class Car {
    @Id
    @GeneratedValue(generator = "inc")
    @GenericGenerator(name = "inc", strategy = "increment")
    private int id;
    @NotBlank(message = "car name`s must be not empty")
    private String name;
    private LocalDateTime productionYear;
    private boolean tested;

    public Car() {
    }

    public Car(@NotBlank(message = "car name`s must be not empty") String name, LocalDateTime productionYear) {
        this.name = name;
        this.productionYear = productionYear;
    }
}

我想知道如何在 Spring 中測試 POST 方法。 下面是 POST 方法的代碼片段,它只創建名為 Car 的 Java object(第一個片段)

 @PostMapping("/cars")
ResponseEntity<Car> createCar(@RequestBody @Valid Car newCar) {
    logger.info("Creating new car");
    var result = repository.save(newCar);
    return ResponseEntity.created(URI.create("/" + result.getId())).body(result);
}

我正在嘗試以這種方式對其進行測試:

package github.KarolXX.demo.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import github.KarolXX.demo.TestConfiguration;
import github.KarolXX.demo.model.Car;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import java.time.LocalDateTime;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("integration")
class CarControllerIntegrationServerSideTest {
    @Autowired
    private MockMvc mockMvc;    

    @Test
    public void httpPost_createsNewCar_returnsCreatedCar() throws Exception {
        //given
        Car car = new Car("second server side test", LocalDateTime.parse("2021-01-02T13:34:54"));

        //when + then
        mockMvc.perform(post("/cars")
                .content(asJsonString(car))
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(status().isCreated());
    }

    public static String asJsonString(final Car objectCar) {
        try {
            return new ObjectMapper().writeValueAsString(objectCar);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}



   

我是根據這篇文章做到的 不幸的是我的測試沒有通過。 雖然在日志中我可以看到請求正文和請求標頭設置正確,但我得到狀態 400

2021-03-26 12:05:01.532  WARN 10696 --- [           main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Expected array or string.; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string.
 at [Source: (PushbackInputStream); line: 1, column: 59] (through reference chain: github.KarolXX.demo.model.Car["productionYear"])]

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /cars
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", Content-Length:"279"]
             Body = {"id":0,"name":"second server side test","productionYear":{"month":"JANUARY","dayOfWeek":"SATURDAY","dayOfYear":2,"nano":0,"year":2021,"monthValue":1,"dayOfMonth":2,"hour":13,"minute":34,"second":54,"chronology":{"id":"ISO","calendarType":"iso8601"}},"tested":false,"brand":null}
    Session Attrs = {}

Handler:
             Type = github.KarolXX.demo.controller.CarController
           Method = github.KarolXX.demo.controller.CarController#createCar(Car)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /cars
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Accept:"application/json", Content-Length:"279"]
             Body = {"id":0,"name":"second server side test","productionYear":{"month":"JANUARY","dayOfWeek":"SATURDAY","dayOfYear":2,"nano":0,"year":2021,"monthValue":1,"dayOfMonth":2,"hour":13,"minute":34,"second":54,"chronology":{"id":"ISO","calendarType":"iso8601"}},"tested":false,"brand":null}
    Session Attrs = {}

Handler:
             Type = github.KarolXX.demo.controller.CarController
           Method = github.KarolXX.demo.controller.CarController#createCar(Car)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = org.springframework.http.converter.HttpMessageNotReadableException

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 400
    Error message = null
          Headers = []
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

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

我不知道可能出了什么問題,但是當我將這行代碼mockMvc.perform(post("/cars")更改為這一行mockMvc.perform(post("/")時,我得到了狀態 404

我已經解決了這個問題,但是我不知道為什么以前的版本不起作用。 我從測試 class 中刪除了 static 方法並更改了 POST 方法檢查:即我創建了一個將 JSON 作為字符串保存的變量並將其傳遞給content方法。 在以前的版本中,此字符串由ObjectMapper().writeValueAsString()在 static 方法中返回。 我修改后的測試 class:

@Test
public void httpPost_createsNewCar_returnsCreatedCar() throws Exception {
    //given
    //Car car = new Car("second server side test", LocalDateTime.parse("2021-01-02T13:34:54"));
    String id = String.valueOf(repo.getSize());
    String jsonString = new JSONObject()
            .put("id", id)
            .put("tested", false)
            .put("productionYear", "2017-06-18T12:12:12")
            .put("name", "Toyota")
            .toString();

    //when + then
    mockMvc.perform(post("/cars")
            .content(jsonString)
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON))
            .andDo(MockMvcResultHandlers.print())
            .andExpect(status().isCreated());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM