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

Mock含Pageable参数的Repository方法时触发空指针异常求助

Spring Boot单元测试Mock带Pageable的Repository方法空指针问题解决

核心问题分析

你遇到的空指针是因为Mock的Repository方法没有返回有效的Page对象,导致Service中调用animals.getContent()时animals为null。默认情况下,Mockito对未指定返回值的Mock方法会返回null,必须显式配置该方法的返回结果。

具体解决方案

1. 构造Mock Page实例返回

使用Spring Data提供的PageImpl(Page接口的实现类)构造测试用的分页对象,让Mock的Repository方法返回该实例:

// 构造测试数据列表
List<Animal> testAnimals = Arrays.asList(new Animal("cat", "male"), new Animal("dog", "female"));
// 包装为Page对象
Page<Animal> mockPage = new PageImpl<>(testAnimals);

// Mock Repository方法,匹配任意参数(包括Pageable)
when(animalRepository.findAllByTypeContainsAndSexLike(anyString(), anyString(), any(Pageable.class)))
    .thenReturn(mockPage);

2. 确保参数匹配准确

如果测试中指定了具体参数值,必须保证和实际调用的参数完全匹配,否则Mockito不会触发配置的返回值,仍会返回null。比如:

// 假设测试时传入的参数是"cat"和"male"
when(animalRepository.findAllByTypeContainsAndSexLike("cat", "male", any(Pageable.class)))
    .thenReturn(mockPage);

3. 验证Mock方法的调用情况

在测试末尾添加验证,确认Repository方法确实被调用,排除因方法未执行导致的null:

verify(animalRepository, times(1))
    .findAllByTypeContainsAndSexLike(anyString(), anyString(), any(Pageable.class));

完整测试类示例

假设你的Service方法如下:

@Service
public class AnimalService {
    @Autowired
    private AnimalRepository animalRepository;

    public List<Animal> getAnimals(String type, String sex, Pageable pageable) {
        Page<Animal> animals = animalRepository.findAllByTypeContainsAndSexLike(type, sex, pageable);
        return animals.getContent(); // 此处animals为null会抛出空指针
    }
}

对应的测试类实现:

@ExtendWith(MockitoExtension.class)
public class AnimalServiceTest {
    @Mock
    private AnimalRepository animalRepository;

    @InjectMocks
    private AnimalService animalService;

    @Test
    public void getAnimalsTest() {
        // 构造测试数据
        List<Animal> testData = Arrays.asList(new Animal("cat", "male"));
        Page<Animal> mockPage = new PageImpl<>(testData);

        // 配置Mock返回
        when(animalRepository.findAllByTypeContainsAndSexLike(anyString(), anyString(), any(Pageable.class)))
                .thenReturn(mockPage);

        // 调用Service方法
        List<Animal> result = animalService.getAnimals("cat", "male", PageRequest.of(0, 10));

        // 断言结果正确性
        assertEquals(1, result.size());
        // 验证Repository方法被调用
        verify(animalRepository).findAllByTypeContainsAndSexLike("cat", "male", PageRequest.of(0, 10));
    }
}

常见坑点提醒

  • 不要忘记添加@ExtendWith(MockitoExtension.class)(JUnit 5)或@RunWith(MockitoJUnitRunner.class)(JUnit 4),否则Mock注解无法生效。
  • 如果使用@SpringBootTest做集成测试,需用@MockBean替代@Mock和@InjectMocks来注入Mock实例。
  • 注意Pageable参数的匹配,避免因PageRequest的页码、大小不匹配导致Mock逻辑不触发。

内容的提问来源于stack exchange,提问作者Artem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:34:58