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

如何Mock Properties.load()方法?解决测试中空指针异常问题

问题分析与解决方案

核心问题

  1. 静态方法无法被Mockito普通Mock:你的loadProperties是静态方法,Mockito默认不支持Mock静态方法,测试里创建的Properties Mock对象完全没被用到,实际调用的还是原方法里new出来的Properties实例。
  2. 资源流返回Null:Foo.class.getClassLoader().getResourceAsStream("id")找不到指定资源,返回null,调用properties.load(null)直接抛出空指针异常。
  3. 代码语法错误:原loadProperties方法的return语句位置错误,应放在方法块内;getSomething方法里的something变量未定义,会导致编译错误。

修复步骤

1. 修正Foo类的语法与基础逻辑

public class Foo {
    // 定义所需的变量,示例设为字符串常量
    private static final String something = "target_key";

    public A getSomething() {
        Properties properties = loadProperties().getProperty(something);
        // 补充返回逻辑,根据实际业务调整
        return new A();
    }

    public static Properties loadProperties() {
        Properties properties = new Properties();
        try {
            InputStream inputStream = Foo.class.getClassLoader().getResourceAsStream("id");
            if (inputStream != null) {
                properties.load(inputStream);
            } else {
                // 处理资源找不到的场景,避免后续空指针
                throw new IOException("配置文件'id'未找到");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }
}

2. 测试方案调整

针对静态方法的Mock需求,有两种可行方案:

方案一:使用Mockito-inline支持静态Mock

确保依赖中引入mockito-inline(Mockito 3.4+版本支持),修改测试代码如下:

import org.junit.Test;
import org.mockito.Mockito;
import java.util.Properties;

public class FooTest {
    @InjectMocks
    Foo foo = new Foo();

    @Test
    public void test() throws Exception {
        // Mock静态方法loadProperties
        try (Mockito.MockedStatic<Foo> mockedFoo = Mockito.mockStatic(Foo.class)) {
            Properties mockProps = Mockito.mock(Properties.class);
            // 指定静态方法返回Mock的Properties实例
            mockedFoo.when(Foo::loadProperties).thenReturn(mockProps);
            // 按需Mock getProperty的返回值
            Mockito.when(mockProps.getProperty("target_key")).thenReturn("test_value");

            foo.getSomething();
            // 验证静态方法是否被调用
            mockedFoo.verify(Foo::loadProperties);
        }
    }
}

方案二:重构代码,移除静态方法(更推荐的设计)

将配置加载逻辑抽成独立类,改为实例依赖,便于Mock:

// 独立的配置加载类
public class PropertyLoader {
    public Properties loadProperties() throws IOException {
        Properties properties = new Properties();
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream("id");
        if (inputStream == null) {
            throw new IOException("配置文件'id'未找到");
        }
        properties.load(inputStream);
        return properties;
    }
}

// 修改Foo类,通过构造方法注入依赖
public class Foo {
    private static final String something = "target_key";
    private PropertyLoader propertyLoader;

    public Foo(PropertyLoader propertyLoader) {
        this.propertyLoader = propertyLoader;
    }

    public A getSomething() {
        try {
            Properties properties = propertyLoader.loadProperties().getProperty(something);
            return new A();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

对应的测试代码(无需处理静态方法,逻辑更简洁):

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Properties;

@RunWith(MockitoJUnitRunner.class)
public class FooTest {
    @Mock
    PropertyLoader mockPropertyLoader;

    @InjectMocks
    Foo foo;

    @Test
    public void test() throws Exception {
        Properties mockProps = Mockito.mock(Properties.class);
        Mockito.when(mockPropertyLoader.loadProperties()).thenReturn(mockProps);
        Mockito.when(mockProps.getProperty("target_key")).thenReturn("test_value");

        foo.getSomething();

        // 验证依赖方法的调用情况
        Mockito.verify(mockPropertyLoader).loadProperties();
        Mockito.verify(mockProps).getProperty("target_key");
    }
}

3. 资源文件注意事项

确保id配置文件放在项目的classpath目录下(比如src/main/resources),这样getResourceAsStream才能正确读取到文件,避免返回null引发空指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 21:25:30