我正在构建一个SpringBootAPI来学习这个框架,我面临着两个奇怪的问题,它们可能以某种方式联系在一起。
第一个问题,当我尝试使用自己的Junit测试类EmployeeControllerTest测试代码时,使用http请求调用方法会返回以下错误:jakarta.servlet.ServletException:请求处理失败:java.util.NoSuchElementException:无数值
第二个问题,当我用Postman执行这些测试时,返回雇员列表的请求/雇员工作得很好,但是请求/雇员(在url中添加或不添加id),API什么也不返回。
除此之外,从代码内部(在run类中)调用方法效果很好,我得到了我需要的每一个结果。
下面是涉及到的每个部分的代码。首先是模型类:
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;
}
存储库类:
package com.openclassrooms.api.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.openclassrooms.api.models.Employee;
@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
服务类别:
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.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 Employee getEmployee(@PathVariable("id") final Long id) {
Optional<Employee> emp = employeeService.getEmployee(id);
if (emp.isEmpty()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
return null;
}
}
@GetMapping("/employee")
public Employee getEmployee() {
Optional<Employee> emp = employeeService.getEmployee(1L);
if (emp.isEmpty()) {
Employee employe = emp.get();
System.out.println(employe.getFirstName());
return employe;
} else {
System.out.println("ABSENT");
return null;
}
}
}
此外,主要类别和测试类别:
package com.openclassrooms.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.openclassrooms.api.models.Employee;
import com.openclassrooms.api.service.EmployeeService;
@SpringBootApplication
public class ApiApplication implements CommandLineRunner {
@Autowired
private EmployeeService employeeService;
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
public void run(String... args) throws Exception {
if (employeeService.getEmployee(1L).isPresent()) {
Employee emp1 = employeeService.getEmployee(1L).get();
System.out.println(emp1.getFirstName() + " " + emp1.getLastName());
} else {
System.out.println("Erreur, employé absent.");
}
System.out.println(employeeService.getEmployees());
}
}
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"))
.andExpect(status().isOk())
.andDo(print(System.out))
.andExpect(jsonPath("$.firstName").value("Laurent"));
//.andExpect(jsonPath("$[0].firstName", is("Laurent")));
}
}
提前感谢您的回答!
EDIT:构建数据库时使用的SQL脚本:
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
id INT AUTO_INCREMENT PRIMARY KEY,
first_name VARCHAR(250) NOT NULL,
last_name VARCHAR(250) NOT NULL,
mail VARCHAR(250) NOT NULL,
password VARCHAR(250) NOT NULL
)
INSERT INTO employees (first_name, last_name, mail, password) VALUES
('Laurent', 'GINA', 'laurentgina@mail.com', 'laurent'),
('Sophie', 'FONCEK', 'sophiefoncek@mail.com', 'sophie'),
('Agathe', 'FEELING', 'agathefeeling@mail.com', 'agathe');
1条答案
按热度按时间unguejic1#
代码似乎有几个问题。
首先,在EmployeeController类的getEmployee方法中,if条件检查employeeService返回的Optional是否为空,但如果为空,则代码返回null,这不是所需的行为。相反,您应该检查Optional是否存在,如果存在,则返回值,否则返回相应的响应,指示未找到该员工。
同样的问题也适用于没有路径变量的getEmployee方法。
关于Junit测试类的问题,如果没有更多的信息,比如确切的错误消息或测试类的代码片段,很难确定问题所在。
总的来说,代码在处理找不到员工的情况时需要更加健壮,并且需要进一步调查测试类以确定问题的根本原因。