Spring+JUnit5+Mockito搭建控制器测试报错排查请求
你遇到的java.lang.NoSuchMethodError: org.mockito.internal.configuration.plugins.Plugins.getMockitoLogger()错误,本质是类路径中存在不兼容的Mockito版本冲突:
- REST-Assured的
spring-mock-mvc依赖特定版本的Mockito,而你显式引入的Mockito 3.x系列和这个依赖版本不兼容——Mockito 3.x对内部API做了调整,移除/修改了REST-Assured调用的Plugins.getMockitoLogger()方法。 - 同时你排除了
spring-boot-starter-test自带的mockito-core,但没有显式引入对应版本的mockito-core,导致依赖传递带来的版本混乱。
1. 统一Mockito版本,解决依赖冲突
首先,在你的POM中显式引入和mockito-junit-jupiter同版本的mockito-core,确保版本完全一致:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>${mockito-junit-jupiter.version}</version> <scope>test</scope> </dependency>
因为你已经排除了spring-boot-starter-test中的mockito-core,必须手动引入匹配版本的核心库,避免依赖传递带来的低版本Mockito混入类路径。
2. 调整REST-Assured或Mockito版本,确保兼容性
根据你的Java 8限制,有两种选择:
选项A:降级Mockito到和REST-Assured 3.3.0兼容的版本
REST-Assured 3.3.0依赖的是Mockito 2.x系列(具体是2.28.2),所以修改你的版本属性:
<properties> <!-- 其他属性保持不变 --> <mockito-junit-jupiter.version>2.28.2</mockito-junit-jupiter.version> </properties>
这样Mockito版本和REST-Assured的依赖完全匹配,避免API调用冲突。
选项B:升级REST-Assured到支持Java 8+和Mockito 3.x的版本
REST-Assured 4.x系列支持Java 8,且兼容Mockito 3.x。你可以升级到4.3.3(支持Java 8的最后一个稳定版本):
<properties> <!-- 其他属性保持不变 --> <spring-mock-mvc.version>4.3.3</spring-mock-mvc.version> </properties>
这个版本既支持Java 8,也能和你当前使用的Mockito 3.4.3/3.5.13兼容。
3. 修正测试类中的@InjectMocks使用问题
你的测试类中同时对userController和controllerExceptionHandler使用@InjectMocks,这可能导致依赖注入混乱:
- 如果
ControllerExceptionHandler没有依赖需要Mock的对象,直接实例化即可,不需要@InjectMocks:
// 替换@InjectMocks private ControllerExceptionHandler controllerExceptionHandler = new ControllerExceptionHandler();
- 如果它确实有依赖,单独为其创建对应的
@Mock对象,再用@InjectMocks注入:
@Mock private SomeExceptionHandlerDependency handlerDependency; // 假设存在这个依赖 @InjectMocks private ControllerExceptionHandler controllerExceptionHandler;
4. 验证依赖树(可选但推荐)
运行Maven命令检查所有Mockito相关依赖的版本,确保没有冲突:
mvn dependency:tree | grep mockito
输出中所有Mockito相关的依赖版本应该完全一致。
确保Lombok版本和你的Spring Boot版本兼容(比如Spring Boot 2.x对应Lombok 1.18.x),虽然这不是当前报错的直接原因,但能避免后续潜在问题。
内容的提问来源于stack exchange,提问作者William Jones

