使用MongoRepository测试查询时遇空指针异常求助
解决调用findByEmailAddress时的空指针异常问题
我太懂你现在的糟心处境了——测试控制器调用服务层的findByEmailAddress方法时突然炸出空指针,肯定对着代码挠头半天对吧?结合你说的这个方法是由带@Query注解的CustomerRepository提供的,我来帮你拆解下最常见的问题和解决办法:
一、90%的概率:依赖没正确注入
空指针十有八九是某个对象没被Spring实例化并注入,按这个顺序排查:
1. 检查服务类的Repository注入
确保你的服务类里,CustomerRepository是通过Spring管理的方式注入的,优先用构造函数注入(比@Autowired字段注入更可靠,能避免很多空指针):
@Service public class CustomerService { private final CustomerRepository customerRepository; // 构造函数注入:Spring会自动把Repository实例传进来 public CustomerService(CustomerRepository customerRepository) { this.customerRepository = customerRepository; } public Customer findByEmailAddress(String email) { return customerRepository.findByEmailAddress(email); } }
别忘了给服务类加@Service注解,让Spring识别并管理这个Bean。
2. 检查控制器的服务注入
控制器里的CustomerService同样要正确注入,还是推荐构造函数注入:
@RestController public class CustomerController { private final CustomerService customerService; public CustomerController(CustomerService customerService) { this.customerService = customerService; } @GetMapping("/customers/email") public ResponseEntity<Customer> getCustomerByEmail(@RequestParam String email) { Customer customer = customerService.findByEmailAddress(email); return ResponseEntity.ok(customer); } }
3. 测试类的上下文配置必须到位
你的JUnit测试类得让Spring加载上下文,才能自动注入依赖。如果是Spring Boot项目,分两种场景:
- 控制器切片测试(轻量):用
@WebMvcTest,只加载控制器相关Bean,同时用@MockBean模拟服务层,避免依赖真实数据库:@WebMvcTest(CustomerController.class) public class CustomerControllerTest { @Autowired private MockMvc mockMvc; // 模拟服务层,不用调用真实Repository @MockBean private CustomerService customerService; @Test public void testFindByEmail() throws Exception { // 预设返回值 Customer mockCustomer = new Customer(); mockCustomer.setEmail("test@example.com"); when(customerService.findByEmailAddress("test@example.com")).thenReturn(mockCustomer); // 执行请求并断言 mockMvc.perform(get("/customers/email").param("email", "test@example.com")) .andExpect(status().isOk()) .andExpect(jsonPath("$.email").value("test@example.com")); } } - 全上下文测试:用
@SpringBootTest,会加载完整的Spring上下文,这时候要确保测试用的数据库配置正确(比如用H2内存数据库)。
二、检查Repository的@Query注解是否正确
如果findByEmailAddress是自定义的@Query方法,也可能是注解里的语句写错了(虽然这一般不会直接导致空指针,但会引发后续问题):
@Repository public interface CustomerRepository extends JpaRepository<Customer, Long> { // 确保JPQL语句里的字段名和实体类一致,参数绑定正确 @Query("SELECT c FROM Customer c WHERE c.emailAddress = :email") Customer findByEmailAddress(@Param("email") String email); }
重点核对:实体类的字段名、@Param的参数名是否和JPQL里的占位符匹配。
三、精准定位空指针的来源
你提到有“崩溃行”,先定位到底哪一行抛的空指针:
- 如果是控制器里的
customerService.findByEmailAddress(...):说明customerService是null,控制器的服务注入失败; - 如果是服务类里的
customerRepository.findByEmailAddress(...):说明customerRepository是null,服务类的Repository注入失败; - 如果是Repository方法内部抛的:大概率是
@Query语句错误或者数据库连接问题。
加个断点或者打印日志,看哪个对象是null,就能精准修复了。
内容的提问来源于stack exchange,提问作者invincibles04
相关产品推荐
相关产品推荐

