You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java17升级:JMockit测试代码转Mockito方案咨询

将JMockit测试转换为Mockito(适配Java 17)

1. 引入Mockito依赖

先在构建文件中添加Mockito核心依赖,若使用JUnit 5,还需集成JUnit Jupiter的适配包(以Maven为例):

<!-- Mockito核心依赖 -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.11.0</version> <!-- 建议使用最新稳定版 -->
    <scope>test</scope>
</dependency>

<!-- JUnit 5集成包(JUnit 5环境下添加) -->
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>

2. 改造测试类

JMockit通过MockUp实现类级Mock,Mockito则侧重实例级的Mock/Spy。根据测试需求分两种场景改造:

场景1:完全Mock Client类(所有方法用模拟实现)

如果测试不需要Client的真实逻辑,仅需模拟clentDetail方法:

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.Mockito.when;

public class Test {
    // 声明Mock实例
    @Mock
    private Client client;

    @Before
    public void init() {
        // 初始化Mockito注解
        MockitoAnnotations.openMocks(this);
        mockClient(true, true);
    }

    private void mockClient(boolean arg1, boolean arg2) {
        // 模拟clentDetail方法的行为
        when(client.clentDetail(anyMap())).thenAnswer(invocation -> {
            ClientTO clientTO = new ClientTO();
            // 迁移原JMockit中的模拟逻辑,比如根据arg1/arg2设置属性
            if (arg1) {
                clientTO.setSomeField("mockValue1");
            }
            if (arg2) {
                clientTO.setAnotherField("mockValue2");
            }
            // 原代码中do something的逻辑移至此处
            return clientTO;
        });
    }

    // 测试方法示例
    @Test
    public void testClientDetail() {
        ClientTO result = client.clentDetail(Map.of("testKey", "testValue"));
        // 后续断言逻辑...
    }
}

场景2:部分Mock Client类(仅替换clentDetail方法,其他方法保留真实逻辑)

若需要保留Client其他方法的真实实现,仅替换clentDetail,使用Spy:

import org.junit.Before;
import org.junit.Test;
import org.mockito.Spy;
import org.mockito.MockitoAnnotations;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.Mockito.doAnswer;

public class Test {
    // 基于真实对象创建Spy实例
    @Spy
    private Client client = new Client();

    @Before
    public void init() {
        MockitoAnnotations.openMocks(this);
        mockClient(true, true);
    }

    private void mockClient(boolean arg1, boolean arg2) {
        // 用doAnswer避免触发真实方法逻辑
        doAnswer(invocation -> {
            ClientTO clientTO = new ClientTO();
            // 迁移原JMockit中的模拟逻辑
            if (arg1) {
                clientTO.setSomeField("mockValue1");
            }
            if (arg2) {
                clientTO.setAnotherField("mockValue2");
            }
            return clientTO;
        }).when(client).clentDetail(anyMap());
    }

    // 测试方法示例
    @Test
    public void testClientDetailWithSpy() {
        ClientTO result = client.clentDetail(Map.of("testKey", "testValue"));
        // 后续断言逻辑...
    }
}

3. Java 17适配注意事项

  • 模块权限:若项目使用Java模块(module-info.java),需允许Mockito访问被测试类,在module-info.java中添加:
    opens com.your.package to org.mockito;
    
    或在测试运行时添加VM参数:
    --add-opens com.your.package/com.your.package.client=org.mockito
    
  • 参数匹配:若需要精确匹配Map参数,替换anyMap()为eq(targetMap)或自定义匹配器。
  • 方法拼写:注意原代码中方法名是clentDetail(疑似少写一个i),若为拼写错误建议统一修正,避免后续问题。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:04:54