You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JUnit测试类中实例化Interface对象?解决空指针异常

解决方案

问题根源

  1. JUnit版本混用:测试类同时使用了JUnit 4的org.junit.Test和JUnit 5的扩展注解,导致Spring依赖注入机制未生效,@Autowired标注的roleService等Bean无法初始化,触发NullPointerException。
  2. 依赖未完整注入:doctorRepository、weekScheduleService等依赖仅声明私有字段但未添加@Autowired,后续调用也会引发空指针。
  3. 日期格式化错误:SimpleDateFormat构造参数传入具体日期而非格式字符串,会导致日期解析失败。
  4. 构造函数不符合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 11:27:27