JUnit中@BeforeEach的setUP()方法抛出NullPointerException求助
问题根源分析
你遇到的NullPointerException核心原因很明确:你使用了Mockito的@Mock注解,但没有让JUnit启用Mockito的注解处理器。这导致dataServiceMock变量始终是null(没有被实例化为Mock对象),调用when(dataServiceMock.retreiveAllData())时自然会触发空指针异常。
解决方案步骤
1. 启用Mockito扩展(关键操作)
在测试类上添加@ExtendWith(MockitoExtension.class)注解,它会告诉JUnit 5使用Mockito扩展来自动初始化所有@Mock标注的对象。
2. 修复并复用@BeforeEach初始化逻辑
恢复你之前注释掉的初始化代码,现在dataServiceMock能被正确实例化,就可以正常设置Mock的返回值,再初始化业务类实例。
3. 清除测试方法中的冗余代码
每个测试方法里重复创建Mock、初始化业务类的代码都可以删掉,直接复用@BeforeEach中初始化好的businessImpl,大幅减少代码冗余。
修改后的完整测试类代码
package com.floatanddouble.mockitodemo; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.when; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) // 启用Mockito注解处理器 class SomeBusinessImplMockAnnotationsTest { @Mock DataService dataServiceMock; SomeBusinessImpl businessImpl; CreateData createData = new CreateData(); GetActualResult getActualResult = new GetActualResult(); @BeforeEach void setUp() { // 修正方法名拼写规范 // 默认初始化10个元素的测试数据 int[] createdData = createData.getCreatedData(10); when(dataServiceMock.retreiveAllData()).thenReturn(createdData); businessImpl = new SomeBusinessImpl(dataServiceMock); } @Test void testFindTheGreatestFromAllData() { // 修正方法名拼写错误 int expectedResult = businessImpl.findTheGreatestFromAllData(); int actualResult = getActualResult.getActualResult(businessImpl.getData()); assertEquals(expectedResult, actualResult); } @Test void testFindTheGreatestFromAllDataTwoElement() { // 覆盖Mock行为,使用2个元素的测试数据 int[] createdData = createData.getCreatedData(2); when(dataServiceMock.retreiveAllData()).thenReturn(createdData); // 重新实例化业务类(构造函数会在初始化时调用retreiveAllData()) businessImpl = new SomeBusinessImpl(dataServiceMock); int expectedResult = businessImpl.findTheGreatestFromAllData(); int actualResult = getActualResult.getActualResult(businessImpl.getData()); assertEquals(expectedResult, actualResult); } @Test void testFindTheGreatestFromAllDataForSingleElement() { int[] createdData = createData.getCreatedData(1); when(dataServiceMock.retreiveAllData()).thenReturn(createdData); businessImpl = new SomeBusinessImpl(dataServiceMock); int expectedResult = businessImpl.findTheGreatestFromAllData(); int actualResult = getActualResult.getActualResult(businessImpl.getData()); assertEquals(expectedResult, actualResult); } }
额外说明
- 业务类构造函数的注意点:你的
SomeBusinessImpl构造函数会直接调用dataService.retreiveAllData()并赋值给data变量,所以如果测试中需要修改Mock的返回值,必须在修改后重新实例化businessImpl,否则构造函数会提前使用旧的Mock行为。 - 代码规范优化:我修正了一些拼写错误(比如
setUP改成setUp、testFnd改成testFind),让代码更易读。 - 辅助类复用:把
CreateData和GetActualResult的实例移到类级别,避免在每个测试方法里重复创建,进一步减少冗余。
内容的提问来源于stack exchange,提问作者amethyst stan
相关产品推荐
相关产品推荐

