如何在JUnit测试类中实例化Interface对象?解决空指针异常
解决方案
问题根源
- JUnit版本混用:测试类同时使用了JUnit 4的
org.junit.Test和JUnit 5的扩展注解,导致Spring依赖注入机制未生效,@Autowired标注的roleService等Bean无法初始化,触发NullPointerException。 - 依赖未完整注入:
doctorRepository、weekScheduleService等依赖仅声明私有字段但未添加@Autowired,后续调用也会引发空指针。 - 日期格式化错误:
SimpleDateFormat构造参数传入具体日期而非格式字符串,会导致日期解析失败。 - 构造函数不符合JUnit规则:JUnit测试类要求仅保留一个公共无参构造函数,带参数的构造函数会触发报错。
修复步骤
1. 统一使用JUnit 5注解
将测试方法的注解从JUnit 4的org.junit.Test替换为JUnit 5的org.junit.jupiter.api.Test,移除多余的@ExtendWith注解(@SpringBootTest已包含JUnit 5自动扩展支持)。
2. 完整注入所有Spring管理Bean
对所有需要的依赖字段添加@Autowired注解,避免在测试方法中手动实例化(如ModelMapper、BCryptPasswordEncoder,需确保这些类已通过Spring配置类注册为Bean)。
3. 修复日期格式化代码
将SimpleDateFormat构造参数改为正确的格式字符串"yyyy-MM-dd",解决日期解析异常问题。
4. 移除错误构造函数
删除带参数的构造函数,仅保留默认无参构造函数(Java会自动生成,可省略显式声明)。
修改后的完整测试代码
package com.doctorAppointmentBookingSystem.serviceImpl; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.junit.jupiter.api.Test; import org.modelmapper.ModelMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import com.doctorAppointmentBookingSystem.entity.Doctor; import com.doctorAppointmentBookingSystem.entity.Role; import com.doctorAppointmentBookingSystem.entity.User; import com.doctorAppointmentBookingSystem.entity.WeekSchedule; import com.doctorAppointmentBookingSystem.model.bindingModel.DoctorRegistrationModel; import com.doctorAppointmentBookingSystem.model.bindingModel.UserRegistrationModel; import com.doctorAppointmentBookingSystem.repository.DoctorRepository; import com.doctorAppointmentBookingSystem.repository.UserRepository; import com.doctorAppointmentBookingSystem.service.RoleService; import com.doctorAppointmentBookingSystem.service.WeekScheduleService; @SpringBootTest public class DoctorServiceImplTest { @Autowired private ModelMapper modelMapper; @Autowired private DoctorRepository doctorRepository; @Autowired private WeekScheduleService weekScheduleService; @Autowired private BCryptPasswordEncoder bCryptPasswordEncoder; @Autowired private RoleService roleService; @Autowired private UserRepository userRepository; @Test public void saveDoctor() throws ParseException { // 修复日期格式:使用正确的格式字符串 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date birthDate = dateFormat.parse("1997-06-25"); Date graduationDate = dateFormat.parse("2010-06-25"); DoctorRegistrationModel doctorRegModel = new DoctorRegistrationModel( "sai@gmail.com", "ajfjdhskjfh", "1234567890", "1234567890", "shfgjdsgh", "shfgjdsgh", "1234567890", birthDate, "MALE", graduationDate); UserRegistrationModel userRegistrationModel = this.modelMapper.map(doctorRegModel, UserRegistrationModel.class); String DEFAULT_DOCTOR_ROLE = "ROLE_DOCTOR"; userRegistrationModel.setAdditionalRole(DEFAULT_DOCTOR_ROLE); User user = this.modelMapper.map(userRegistrationModel, User.class); String encryptedPassword = this.bCryptPasswordEncoder.encode(userRegistrationModel.getPassword()); user.setPassword(encryptedPassword); user.setAccountNonExpired(true); user.setAccountNonLocked(true); user.setCredentialsNonExpired(true); user.setEnabled(true); if (userRegistrationModel.getAdditionalRole() != null) { Role additionalRole = this.roleService.getRoleByAuthority(userRegistrationModel.getAdditionalRole()); user.addRole(additionalRole); } User savedUser = this.userRepository.saveAndFlush(user); WeekSchedule weekSchedule = this.weekScheduleService.createDefault(); Doctor doctor = this.modelMapper.map(savedUser, Doctor.class); doctor.setUser(savedUser); doctor.setWeekSchedule(weekSchedule); doctorRepository.saveAndFlush(doctor); } }
额外注意事项
- 确保
ModelMapper、BCryptPasswordEncoder已通过Spring配置类注册为Bean,示例配置:
@Configuration public class AppConfig { @Bean public ModelMapper modelMapper() { return new ModelMapper(); } @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } }
- 确保
RoleService的实现类已添加@Service注解,Spring才能扫描并初始化该Bean。
内容的提问来源于stack exchange,提问作者sai
相关产品推荐
相关产品推荐

