使用JUnit 5+Mockito 3测试Spring应用出现myService空指针异常如何解决
问题根因
核心问题为JUnit4与JUnit5注解混用,导致Mockito注解未被测试引擎识别初始化:
你当前测试类导入的@Test属于JUnit5(org.junit.jupiter.api包),但使用的@RunWith(MockitoJUnitRunner.class)、@Before属于JUnit4(org.junit包),JUnit5测试运行环境不会处理JUnit4的Runner注解,因此@Mock、@InjectMocks标注的字段未完成初始化,触发空指针异常。
解决方案(二选一即可)
方案1:适配JUnit5(推荐)
- 移除JUnit4相关注解与导入:删除
@RunWith(MockitoJUnitRunner.class),移除org.junit.Before的导入 - 测试类添加JUnit5的Mockito扩展注解
@ExtendWith(MockitoExtension.class) - 将原
@Before注解替换为JUnit5的@BeforeEach
修改后测试类参考代码:
import static org.mockito.Mockito.when; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; import java.util.ArrayList; import static org.mockito.ArgumentMatchers.anyString; @ExtendWith(MockitoExtension.class) public class MyServiceTest { @Mock private Repository1 repository1; @Mock private Repository2 repository2; @Mock private Repository3 repository3; @Mock private Repository4 repository4; @InjectMocks private MyService myService; @BeforeEach public void setup() { when(repository1.findAll()).thenReturn(new ArrayList<>()); when(repository1.findAllByInput(anyString())).thenReturn(new ArrayList<>()); } @Test void callMyService() { assertTrue(myService.computeValue("123")); } }
依赖检查:需确保测试依赖中引入了Mockito的JUnit5扩展包,Maven配置参考:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-junit-jupiter</artifactId> <version>3.1.0</version> <scope>test</scope> </dependency>
方案2:切回JUnit4
若项目其他测试均基于JUnit4实现,可统一使用JUnit4注解:
- 将
org.junit.jupiter.api.Test替换为org.junit.Test - 将
org.junit.jupiter.api.Assertions.assertTrue替换为org.junit.Assert.assertTrue - 保留原有
@RunWith(MockitoJUnitRunner.class)、@Before注解即可
额外排查点
- 检查Repository泛型定义:你给出的示例中
Repository1 extends JpaRepository<Repository1, String>存在错误,JpaRepository第一个泛型参数应为对应实体类,而非Repository自身,若实际代码存在该问题会导致Mockito初始化异常 - 检查MyService构造函数的参数类型、顺序与测试类中
@Mock标注的字段完全匹配,Mockito按类型优先匹配构造参数,同类型场景下会按字段名匹配 - 不要同时使用
@ExtendWith(MockitoExtension.class)与@RunWith(MockitoJUnitRunner.class),二者选其一即可
内容的提问来源于stack exchange,提问作者b_archer
相关产品推荐
相关产品推荐

