java 测试SpringBoot API时JSON响应为空

cigdeys3  于 2023-02-07  发布在  Java
关注(0)|答案(1)|浏览(171)

我目前正在构建一个SpringBoot API,遇到了以下问题:
当我尝试在测试类中测试GET请求时,返回的JSON为空,日志如下:

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /employee/1
       Parameters = {}
          Headers = []
             Body = null
    Session Attrs = {}
    
Handler:
             Type = com.openclassrooms.api.controller.EmployeeController
           Method = com.openclassrooms.api.controller.EmployeeController#getEmployee(Long)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

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

FlashMap:
       Attributes = null

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

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

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /employee/1
       Parameters = {}
          Headers = []       
            Body = null
    Session Attrs = {}

Handler:
             Type = com.openclassrooms.api.controller.EmployeeController
           Method = com.openclassrooms.api.controller.EmployeeController#getEmployee(Long)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

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

FlashMap:
       Attributes = null

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

我还得到了以下错误:java.lang.AssertionError:JSON路径"$. firstName"处没有值
然而,当我对Postman执行完全相同的GET请求时,我得到了正确的答案。

    • 有关其他信息,我的测试类:**
package com.openclassrooms.api;

import static org.hamcrest.CoreMatchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;

import java.io.PrintStream;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
//import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.ResultHandler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.openclassrooms.api.controller.EmployeeController;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;

//@SpringBootTest
//@AutoConfigureWebMvc
@WebMvcTest(controllers = EmployeeController.class)
public class EmployeeControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private EmployeeService employeeService;

    @Test
    public void testGetEmployees() throws Exception {
        Employee response = new Employee();

        mockMvc.perform(get("/employee/1"))
                .andExpect(status().isOk())
                .andDo(print(System.out))
                .andExpect(jsonPath("$.firstName").value("Laurent"));

        // .andExpect(jsonPath("$[0].firstName", is("Laurent")));
    }
}
    • 控制器类:**
package com.openclassrooms.api.controller;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;

@RestController
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    // Read - Get all employees

    // @return - An Iterable object of Employee full filled

    @GetMapping("/employees")
    public Iterable<Employee> getEmployees() {
        Iterable<Employee> list = employeeService.getEmployees();
        System.out.println(list);
        return list;
    }

    @GetMapping("/employee/{id}")
    public Optional<Employee> getEmployee(@PathVariable("id") final Long id) {
        Optional<Employee> emp = employeeService.getEmployee(id);

        if (emp.isPresent()) {
            System.out.println(emp.get().getFirstName());
            return emp;
        } else {
            System.out.println("ABSENT");
            return null;
        }
    }

    @GetMapping("/employee")
    public Optional<Employee> getEmployee() {
        Optional<Employee> emp = employeeService.getEmployee(1L);

        if (emp.isPresent()) {
            System.out.println(emp.get().getFirstName());
            return emp;
        } else {
            System.out.println("ABSENT");
            return emp;
        }
    }
}
    • 服务类:**
package com.openclassrooms.api.service;

import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.repository.EmployeeRepository;

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    public Optional<Employee> getEmployee(final Long id) {
        System.out.println("getEmployee ok");
        return employeeRepository.findById(id);
    }

    public Iterable<Employee> getEmployees() {
        System.out.println("getEmployees ok");
        return employeeRepository.findAll();
    }

    public void deleteEmployee(final Long id) {
        employeeRepository.deleteById(id);
    }

    public Employee saveEmployee(Employee employee) {
        Employee savedEmployee = employeeRepository.save(employee);
        return savedEmployee;
    }

}
    • 和模型类:**
package com.openclassrooms.api.models;

import jakarta.persistence.*;

import lombok.Data;

@Data
@Entity
@Table(name = "employees")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    private String mail;

    private String password;

}
wgx48brx

wgx48brx1#

你必须先持久化一个实体。语句Employee response = new Employee();并没有在数据库中创建一个实体,它只是创建了一个对象。
所以在你的测试中,你应该首先持久化实体,类似于:

@WebMvcTest(controllers = EmployeeController.class)
public class EmployeeControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private EmployeeService employeeService;

    @Test
    public void testGetEmployees() throws Exception {
        // given
        Employee existingEmployee = new Employee();
        existingEmployee.setFirstName("Laurent"); // <-- set the name you want to test
        employeeService.saveEmployee(response); // <-- persist the entity

        // when
        mockMvc.perform(get("/employee/1"))

        // then
                .andExpect(status().isOk())
                .andDo(print(System.out))
                .andExpect(jsonPath("$.firstName").value("Laurent"));
    }
}

相关问题