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

JUnit4+Mockito仅Mock类中单个静态方法的问题排查

测试静态方法methodA时Mock内部静态方法methodB的问题

待测试类

public class SomeClass {
    public static String methodA(String arg1) {
        return arg1 + methodB();
    }
    public static String methodB() {
        OtherClass other = new OtherClass();
        return OtherClass.doSomethingElse();
    }
}

问题场景

我需要测试methodA,但它依赖静态方法methodB,而methodB又依赖未初始化的OtherClass,所以尝试用Mockito的mockStatic来MockmethodB,测试代码如下:

MockedStatic<SomeClass> someClassInst = mockStatic(SomeClass.class);
someClassInst.when(() -> SomeClass.methodB()).thenReturn("testStr");
someClassInst.when(() -> SomeClass.methodA(anyString())).thenCallRealMethod();

但调用String result = SomeClass.methodA("test")时始终抛出空指针异常,调试发现methodA执行return语句时触发异常,试过spy但问题更多,想问是否能用Mock实现需求。

当前依赖配置

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter</artifactId>
    <version>5.5.2</version>
    <scope>test</scope>
</dependency>


<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.7.0</version>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.7.0</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-engine</artifactId>
    <version>1.5.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    <version>5.4.0</version>
    <scope>test</scope>
</dependency>


<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.4.0</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>3.1.0</version>
    <scope>test</scope>
</dependency>

问题原因及解决方案

原因分析

当使用mockStatic(SomeClass.class)时,默认会Mock该类的所有静态方法,此时即使你给methodA设置thenCallRealMethod,methodA内部直接调用的methodB并不会走Mockito的Mock代理,而是执行真实的methodB逻辑——这才是空指针的根源(真实methodB里的OtherClass或doSomethingElse()未被正确初始化)。

修正后的测试代码

不需要给methodA设置thenCallRealMethod,直接调用真实的methodA即可,同时确保methodB的Mock生效。另外,必须用try-with-resources管理MockedStatic,避免静态Mock污染其他测试:

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.times;

class SomeClassTest {

    @Test
    void testMethodA() {
        try (MockedStatic<SomeClass> mockedSomeClass = Mockito.mockStatic(SomeClass.class)) {
            // Mock methodB的返回值
            mockedSomeClass.when(SomeClass::methodB).thenReturn("testStr");
            
            // 直接调用methodA,内部会使用Mock的methodB返回值
            String result = SomeClass.methodA("test");
            
            // 验证结果正确性
            assertEquals("testtestStr", result);
            // 验证methodB被调用了一次
            mockedSomeClass.verify(SomeClass::methodB, times(1));
        }
    }
}

依赖优化

你的依赖同时混合了JUnit 4和JUnit 5,容易引发版本冲突,建议统一使用JUnit 5,清理冗余依赖:

  • 移除junit:junit:4.12
  • 移除org.junit.vintage:junit-vintage-engine(如果不需要兼容JUnit 4测试)
  • 统一junit-jupiter、junit-jupiter-engine的版本为一致的版本(比如都用5.5.2)
  • 确保mockito-junit-jupiter版本与mockito-core、mockito-inline版本一致(比如都用3.7.0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 11:37:02