Spring Boot单元测试时Repository为空引发NullPointerException问题求助
解决Spring Boot单元测试中AppointmentRepository为空的NullPointerException
可能的原因及修复步骤
1. 检查Mockito依赖与版本
确保项目依赖中引入了正确的Mockito库,版本需适配JUnit版本:
- Maven配置(
pom.xml):
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>4.11.0</version> <scope>test</scope> </dependency>
- Gradle配置(
build.gradle):
testImplementation 'org.mockito:mockito-core:4.11.0' testImplementation 'org.mockito:mockito-junit-jupiter:4.11.0'
2. 修正测试类的Runner/Extension配置
如果使用JUnit 5(Jupiter),建议替换@RunWith(MockitoJUnitRunner.class)为@ExtendWith(MockitoExtension.class)——JUnit 5不再推荐使用@RunWith注解:
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class AppointmentServiceTest { @Mock private AppointmentRepository appointmentRepository; @InjectMocks private AppointmentService appointmentService; // 测试方法... }
若坚持使用JUnit 4,需确保@RunWith(MockitoJUnitRunner.class)注解生效,同时测试类需符合JUnit 4的识别规则(如类名以Test结尾)。
3. 确保AppointmentService的依赖注入方式正确
@InjectMocks需要依赖类提供可注入的入口,推荐使用Spring官方倡导的构造函数注入:
@Service public class AppointmentService { private final AppointmentRepository appointmentRepository; // 构造函数注入,Mockito可自动注入@Mock实例 public AppointmentService(AppointmentRepository appointmentRepository) { this.appointmentRepository = appointmentRepository; } public List<Appointment> getAllAppointments() { return appointmentRepository.findAll(); } }
如果使用字段注入,需保证字段不是private final,或提供对应的setter方法,否则@InjectMocks无法完成注入。
4. 修正verify方法的写法
原测试中verify(appointmentRepository.findAll())的写法错误,正确调用方式应为:
verify(appointmentRepository).findAll();
需先传入mock对象,再调用待验证的方法,而非直接将方法调用作为参数。
5. 手动初始化Mocks(备选方案)
若以上方法无效,可在测试前手动初始化mock对象:
import org.mockito.MockitoAnnotations; import org.junit.jupiter.api.BeforeEach; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); }
此方法会强制初始化所有标记了@Mock和@InjectMocks的字段。
修复后的完整测试类示例
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import java.util.ArrayList; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) class AppointmentServiceTest { @Mock private AppointmentRepository appointmentRepository; @InjectMocks private AppointmentService appointmentService; @Test void shouldGetAllAppointments() { List<Appointment> appointments = new ArrayList<>(); appointments.add(new Appointment()); given(appointmentRepository.findAll()).willReturn(appointments); List<Appointment> expectedAppointments = appointmentService.getAllAppointments(); assertEquals(expectedAppointments, appointments); verify(appointmentRepository).findAll(); } }
内容的提问来源于stack exchange,提问作者nikolaPantelic98
相关产品推荐
相关产品推荐

