首页 > 解决方案 > Spring Controller 测试:Postman 与 JUnit - 字段错误请求被拒绝值 [null]

问题描述

我是 Spring 框架的初学者,正在尝试测试 Controller。

有趣的是,使用 Postman,我得到了正确的响应,但在 JUnit 中没有收到Actual :400(错误请求)而不是Expected :200.

在此处输入图像描述

在此处输入图像描述

这是由于空字段乘客计数,因为显示为空。请求的类与响应不同。后者没有供乘客使用的字段。

控制器

    @Validated
    @RestController
    @RequestMapping("flights")
    public class BusyFlightsController {


        CrazyAirDatabase crazyAirService;

        @Autowired
        public BusyFlightsController(CrazyAirDatabase crazyAirService) {
            this.crazyAirService = new CrazyAirDatabase();
        }

        @RequestMapping(value = "/crazy-air-response", method = RequestMethod.GET, produces = "application/json")
        public List<CrazyAirResponse> getCrazyAirResponse(
                @Valid CrazyAirRequest crazyAirRequest,
                @RequestParam("origin") String origin,
                @RequestParam("destination") String destination,
                @RequestParam("departureDate") String departureDate,
                @RequestParam("returnDate") String returnDate,
                @RequestParam("passengerCount") int passengerCount
        ) {
            crazyAirRequest = new CrazyAirRequest(origin, destination, departureDate, returnDate,
                    passengerCount);
            return crazyAirService.getCrazyAirResponse(crazyAirRequest);
        }
}

CrazyAirRequest 类

    public class CrazyAirRequest {

        @IATACodeConstraint
        private String origin;
        @IATACodeConstraint
        private String destination;
        private String departureDate;
        private String returnDate;
        private int passengerCount;


        public CrazyAirRequest(String origin, String destination, String departureDate,
                               String returnDate, int passengerCount) {
            this.origin = origin;
            this.destination = destination;
            this.departureDate = departureDate;
            this.returnDate = returnDate;
            this.passengerCount = passengerCount;
        }
    // Getters
}

CrazyAirResponse 类

public class CrazyAirResponse {

    private String airline;
    private double price;
    private String cabinClass;
    private String departureAirportCode;
    private String destinationAirportCode;
    private String departureDate;
    private String arrivalDate;


    public CrazyAirResponse(String airline, double price, String cabinClass, String departureAirportCode,
                            String destinationAirportCode, String departureDate, String arrivalDate) {
        this.airline = airline;
        this.price = price;
        this.cabinClass = cabinClass;
        this.departureAirportCode = departureAirportCode;
        this.destinationAirportCode = destinationAirportCode;
        this.departureDate = departureDate;
        this.arrivalDate = arrivalDate;
    }
// Getters
}

回购 CrazyAirDatabase

@Component
public class CrazyAirDatabase implements CrazyAirService {

    List<CrazyAirResponse> list;

    public CrazyAirDatabase() {
        list = new ArrayList<>(
                Arrays.asList(
                        new CrazyAirResponse("Ryanair", 125, "E", "LHR",
                                "BRN", "2018-10-08", "2020-10-08")             
        );
    }

    @Override
    public List<CrazyAirResponse> getCrazyAirResponse(CrazyAirRequest request) {

        return list.stream()
                .filter(t -> t.getDepartureAirportCode().equals(request.getOrigin()) &&
                        t.getDestinationAirportCode().equals(request.getDestination()) &&
                        t.getDepartureDate().equals(request.getDepartureDate()) &&
                        t.getArrivalDate().equals(request.getReturnDate())
                )
                .collect(Collectors.toList());
    }
}

测试

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

    @Autowired
    MockMvc mockMvc;

    @Mock
    CrazyAirRequest crazyAirRequest;

    @InjectMocks
    private BusyFlightsController controller;

    @Mock
    CrazyAirService service;

    @Before
    public void before() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }


    @Test
    public void testino() throws Exception {

        crazyAirRequest = new CrazyAirRequest("LHR",
                "BRN", "2018-10-08", "2020-10-08", 120);

        List<CrazyAirResponse> crazyAirResponse = Arrays.asList(new CrazyAirResponse("Ryanair", 125,
                        "E", "LHR",
                        "BRN", "2018-10-08", "2020-10-08")

        );

        when(service.getCrazyAirResponse(crazyAirRequest)).thenReturn(crazyAirResponse);

        ObjectMapper objectMapper = new ObjectMapper();
        String airplane = objectMapper.writeValueAsString(crazyAirResponse);

        ResultActions result = mockMvc.perform(get("/flights/crazy-air-response")
                .contentType(MediaType.APPLICATION_JSON)
                .content(airplane)
        );

        result.andExpect(status().isOk());

    }
}

标签: spring-bootjunitcontrollernullpostman

解决方案


如果我把这个:

 ResultActions result = mockMvc.perform(get("/flights/crazy-air-response?origin=LHR&destination=CTA&departureDate=some&returnDate=some&passengerCount=1")
            .contentType(MediaType.APPLICATION_JSON)
            .content(airplane)
    );

测试通过。

那么,需要我先执行Postman,然后复制粘贴查询才能通过测试吗?


推荐阅读