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

测试数据初始化最佳实践:非Spring框架下属性文件替代方案咨询

无Spring框架的属性文件优化方案

1. 单例属性读取器+集中式键常量类

不用为每个模块单独创建类,而是用一个全局单例的属性读取工具类,搭配一个集中管理所有属性键的常量类,既避免重复初始化读取器,又能统一维护键值,杜绝硬编码。

示例代码:

  • 属性读取工具类(单例实现):
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class PropertyReader {
    private static final PropertyReader INSTANCE = new PropertyReader();
    private final Properties properties = new Properties();

    private PropertyReader() {
        // 批量加载所有属性文件,可根据需求添加多个
        loadProperties("login.properties");
        loadProperties("common.properties");
    }

    private void loadProperties(String fileName) {
        try (InputStream is = getClass().getClassLoader().getResourceAsStream(fileName)) {
            if (is != null) {
                properties.load(is);
            }
        } catch (IOException e) {
            throw new RuntimeException("加载属性文件失败: " + fileName, e);
        }
    }

    public static PropertyReader getInstance() {
        return INSTANCE;
    }

    public String getProperty(String key) {
        return properties.getProperty(key);
    }
}
  • 属性键常量类:
public class PropertyKeys {
    // 登录模块相关键
    public static final String LOGIN_BUTTON_TEXT = "login-page.login-button.text";
    public static final String WRONG_PASSWORD_NOTIFICATION = "login-page.notification.wrong-password";
    
    // 其他模块键可在此扩展
}
  • 断言时的调用方式:
Assert.that(actualNotification, PropertyReader.getInstance().getProperty(PropertyKeys.WRONG_PASSWORD_NOTIFICATION));

2. 类型安全的枚举式属性访问器

如果想在编译期就避免传错属性键的问题,可以用枚举封装每个属性的键和读取逻辑,实现类型安全的属性访问,同时省去单独的常量类。

示例代码:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public enum AppProperties {
    LOGIN_BUTTON_TEXT("login-page.login-button.text"),
    WRONG_PASSWORD_NOTIFICATION("login-page.notification.wrong-password");

    private final String key;
    private static Properties properties;

    static {
        // 静态块加载所有属性文件
        try (InputStream loginIs = AppProperties.class.getClassLoader().getResourceAsStream("login.properties")) {
            properties = new Properties();
            properties.load(loginIs);
            // 可追加加载其他属性文件
            properties.load(AppProperties.class.getClassLoader().getResourceAsStream("common.properties"));
        } catch (IOException e) {
            throw new RuntimeException("加载属性文件失败", e);
        }
    }

    AppProperties(String key) {
        this.key = key;
    }

    public String getValue() {
        return properties.getProperty(key);
    }
}
  • 断言时的调用方式:
Assert.that(actualNotification, AppProperties.WRONG_PASSWORD_NOTIFICATION.getValue());

3. 接口式模块化属性分组

如果希望按模块拆分属性键,但又不想每个模块都创建带初始化逻辑的类,可以用接口做模块级的常量容器,搭配统一的单例读取器使用。

示例代码:

// 登录模块属性键接口
public interface LoginPropertyKeys {
    String LOGIN_BUTTON_TEXT = "login-page.login-button.text";
    String WRONG_PASSWORD_NOTIFICATION = "login-page.notification.wrong-password";
}

// 订单模块属性键接口(示例)
public interface OrderPropertyKeys {
    String ORDER_CONFIRM_BUTTON_TEXT = "order-page.confirm-button.text";
}
  • 断言时的调用方式:
Assert.that(actualNotification, PropertyReader.getInstance().getProperty(LoginPropertyKeys.WRONG_PASSWORD_NOTIFICATION));

这几种方案都比创建多个带public static final字段的类更高效:要么减少冗余代码、集中管理配置,要么提供编译期类型安全,要么兼顾模块化与简洁性,且均为纯Java实现,无需依赖Spring框架。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 23:10:55