You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JUnit 5中Mockito重复注入Mock问题排查

解决Mockito 2.17.0 + JUnit 5.1.0 + Spring Boot 2.0.0的@InjectMocks重复注入问题

这个问题我之前踩过同款坑!本质是版本兼容性bug导致的——Mockito 2.17.0和JUnit 5.1.0搭配时,MockitoExtension在处理@InjectMocks注解时会重复执行依赖注入逻辑,最终出现你遇到的Mock被重复注入的异常行为。下面是几个靠谱的解决办法:

1. 升级Mockito到兼容版本(推荐)

Mockito在2.21.0版本修复了和JUnit 5.1.x系列的兼容问题,直接升级Mockito版本就能彻底解决这个问题:

Maven配置

pom.xml里覆盖Spring Boot的默认Mockito版本:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.21.0</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>2.21.0</version>
        </dependency>
    </dependencies>
</dependencyManagement>

Gradle配置

build.gradle里指定Mockito版本:

ext['mockito.version'] = '2.21.0'

dependencies {
    testImplementation 'org.mockito:mockito-junit-jupiter'
}

升级后,你原来的测试代码完全不需要修改,@ExtendWith(MockitoExtension.class)的逻辑就能正常工作,不会再出现重复注入的问题。

2. 手动初始化Mock(临时方案)

如果暂时不能升级版本,可以绕过MockitoExtension,手动在测试类里初始化Mock和注入:

import org.junit.jupiter.api.BeforeEach;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

class MyServiceTest {
    @Mock
    private A a;
    @Mock
    private B b;
    @InjectMocks
    private MyService myService;

    @BeforeEach
    void setUp() {
        // 手动初始化Mock并完成注入
        MockitoAnnotations.initMocks(this);
    }

    // 测试方法...
}

这种方式能避开MockitoExtension的bug,但不如升级版本优雅,毕竟手动初始化会增加测试代码的冗余。

问题根源说明

Mockito 2.17.0的MockitoExtension在处理JUnit 5.1.0的生命周期回调时存在逻辑错误,导致@InjectMocks的注入逻辑被多次触发,最终造成Mock被重复注入到目标Bean中。后续的Mockito版本修复了这个生命周期回调的问题,所以升级是最彻底的解决方式。

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

火山引擎 最新活动