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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 09:48:16