请求处理因空指针异常而失败,因为无法调用服务类,因为它为空。
我正在尝试为我的控制器类编写测试用例。
这是我的用户控制器类
@RestController
@RequestMapping(URLConstants.User)
@Log4j2
@RequiredArgsConstructor(onConstructor = @__({ @Autowired }))
public class UsersController {
private final UserMapper mapper;
private final UserService userService;
@PutMapping("/{id}")
public UserDTO update(@PathVariable("id") Long id, @RequestBody UserUpdateRequest userRequest) {
log.debug("PUT /users/" + id + " with data" + userRequest);
User user = CurrentUserContext.getCurrentUser();
mapper.mergeToUser(userRequest, user);
user = userService.update(user);
return mapper.mapDTO(user);
}
}
为此,这是我的测试课
@SpringBootTest(classes = UsersController.class)
@AutoConfigureMockMvc(addFilters = false)
@ExtendWith(MockitoExtension.class)
public class UsersControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserMapper userMapper;
@MockBean
private UserService userService;
@Mock
private CurrentUserContext currentUserContext;
@InjectMocks
private UsersController usersController;
private final ObjectMapper objectMapper = new ObjectMapper();
@Test
@DisplayName("Test successful user update")
public void testUpdateUserSuccess() throws Exception {
// Prepare test data
Long userId = 1L;
UserUpdateRequest userUpdateRequest = new UserUpdateRequest();
userUpdateRequest.setFirstName("John");
userUpdateRequest.setLastName("Doe");
User updatedUser = new User();
updatedUser.setId(userId);
updatedUser.setFirstName(userUpdateRequest.getFirstName());
updatedUser.setLastName(userUpdateRequest.getLastName());
updatedUser.setStatus(UserStatus.Active);
updatedUser.setCreatedDate(new Timestamp(System.currentTimeMillis()));
updatedUser.setUpdatedDate(new Timestamp(System.currentTimeMillis()));
// Mock the service method
when(userService.update(updatedUser)).thenReturn(updatedUser);
// Perform the request and verify the response
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(usersController).build();
mockMvc.perform(MockMvcRequestBuilders.put("/users/{id}", userId)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(userUpdateRequest)))
.andExpect(status().isOk());
/*.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id").value(userId))
.andExpect(jsonPath("$.firstName").value(userUpdateRequest.getFirstName()))
.andExpect(jsonPath("$.lastName").value(userUpdateRequest.getLastName()));*/
}
@Test
@DisplayName("Test invalid user update request")
public void testUpdateUserInvalidRequest() throws Exception {
// Prepare test data
Long userId = 1L;
UserUpdateRequest userUpdateRequest = new UserUpdateRequest();
// Empty update request
// Perform the request and verify the response
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(usersController).build();
mockMvc.perform(MockMvcRequestBuilders.put("/users/{id}", userId)
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(userUpdateRequest)))
.andExpect(status().isBadRequest());
}
}
现在,即使我是
@MockBean. private UserService userService;
,我也得到`this.userService is null。
Jakarta.servlet.ServletException: Request processing failed: java.lang.NullPointerException: Cannot invoke "com.app.users.services.UserService.update(com.app.users.models.User)" because "this.userService" is null
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1019)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:925)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:550)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
…….
…….
Cannot invoke "com.app.users.services.UserService.update(com.app.users.models.User)" because "this.userService" is null
java.lang.NullPointerException: Cannot invoke "com.app.users.services.UserService.update(com.app.users.models.User)" because "this.userService" is null
at com.app.users.controllers.UsersController.update(UsersController.java:51)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:925)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:550)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:72)
这可能是什么原因。
以下是错误的详细信息以及修复方法:
理解错误:
空指针异常:这是编程中的常见错误,当您尝试使用尚未分配值的变量(即“空”)时,会发生这种错误。在这种情况下,保存服务类的变量为 null,因此您无法调用其方法。 服务类:这是一个为您的程序提供特定功能的类。它可能执行一些与处理请求相关的重要任务。 故障排除步骤:
确定应在何处创建服务类:查找代码中应初始化该服务类的部分。它可能位于配置文件、依赖项注入框架或代码本身中。
确保正确的初始化:确保创建服务类的代码正确运行。如果它在配置文件中,请仔细检查是否有拼写错误或错误。如果它由框架处理,请验证该框架是否设置正确。
检查条件逻辑:如果存在可能阻止在某些条件下创建服务类的代码,请检查该逻辑。例如,配置设置可能决定服务是启用还是禁用。
调试技巧:使用编程环境提供的调试工具逐行调试代码,看看空值来自哪里。