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

JUnit4+Mockito下Jersey项目Mock注入失败,如何Mock静态类方法?

问题分析与解决方案

你的代码存在三个核心问题:

  1. 静态方法无法被普通Mock拦截:ClassA的method1直接调用ClassB.getInstance()这个静态方法获取实例,你用@Mock创建的classBInst和这个静态方法返回的实例完全无关,@InjectMocks也没法替换这种静态获取的对象——因为ClassA根本没有持有ClassB的成员变量,而是每次调用都自己获取。
  2. Mock的方法不匹配:你在setup里Mock的是isClientEnabled()方法,但实际method1调用的是doSomething(),两者完全不对应。
  3. Mockito注解未初始化:你的测试类没有添加@RunWith(MockitoJUnitRunner.class),也没在setup里调用MockitoAnnotations.initMocks(this),导致@Mock和@InjectMocks注解根本没生效,创建的mock对象是无效的。

正确解决方式分两种场景:

场景1:允许修改ClassA代码(推荐,符合依赖注入原则)

重构ClassA,将ClassB的实例通过构造方法注入,而不是直接调用静态方法:

public class ClassA {
    private final ClassB classBInst;

    // 构造注入,方便测试时传入mock对象
    public ClassA(ClassB classBInst) {
        this.classBInst = classBInst;
    }

    public String method1() {
        return classBInst.doSomething();
    }
}

对应的测试类(JUnit4+Mockito):

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class) // 必须添加这个注解,让Mockito处理注解
public class TestClassA {
    @Mock
    private ClassB classBInst;

    private ClassA classAInst;

    @Before
    public void setup() {
        // 手动注入mock对象
        classAInst = new ClassA(classBInst);
        // Mock目标方法doSomething的返回值
        when(classBInst.doSomething()).thenReturn("ReturnStr");
    }

    @Test
    public void testMethod1() {
        String result = classAInst.method1();
        assertEquals("ReturnStr", result);
    }
}

场景2:不能修改ClassA代码(用Mockito静态Mock)

如果无法改动ClassA,需要使用Mockito的静态Mock功能(要求Mockito版本3.4.0及以上),直接MockClassB.getInstance()静态方法,让它返回你创建的mock实例:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class TestClassA {
    @Mock
    private ClassB classBInst;

    @Test
    public void testMethod1() {
        // 静态Mock ClassB类,指定在try块内生效
        try (var mockedStatic = mockStatic(ClassB.class)) {
            // 让getInstance()返回我们的mock实例
            mockedStatic.when(ClassB::getInstance).thenReturn(classBInst);
            // Mock doSomething方法的返回值
            when(classBInst.doSomething()).thenReturn("ReturnStr");

            String result = new ClassA().method1();
            assertEquals("ReturnStr", result);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:41:35