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
相关产品推荐
相关产品推荐

