java - 使用系统属性中的静态最终字段进行单元测试

标签 java junit

我有一个带有公共(public)静态最终字段的接口(interface),该字段是从系统属性中提取的。它看起来像这样:

public interface MyInterface {
    public static final String MYFIELD = System.getProperty("MyField");
    ...
}

我正在编写一个使用该字段的单元测试。即使我在测试前在静态初始化程序中设置系统属性,接口(interface)字段也会返回 null

System.out.println(System.getProperty("MYField")); //returns "MyField"
System.out.println(MyInterface.MYFIELD); //returns null

为什么接口(interface)字段没有设置?处理这种情况的最佳方法是什么?我不能只在测试中设置字段值,因为它是最终静态的。

更新:

我可能错过了一个重要的细节;我正在使用 Mocktio。看起来像这样

public class MyTest {

    static {System.setProperty("MyField", "MyValue");}

    @Test
    public void test1() {
        try {
            final MyInterface mockInterface = Mockito.mock(MyInterface.class);
            ...
        }
     }
}

最佳答案

对您来说有一个坏消息:由于 MYFIELD 字段是静态的,因此会在加载 MyInterface 时评估该字段。因此,如果您的测试类具有对 MyInterface 的静态引用,则它会与您的测试类同时加载。因此,在执行测试之前,您无法选择通过代码设置系统属性。

我怀疑您使用的方法是否良好:通常,接口(interface)应该代表一种行为,而不仅仅是一堆任意常量。但是,如果您实际上需要在接口(interface)的成员中存储一些常量值,那么从 Sytem 属性中获取这些值是无意义的:常量旨在精确地常量

如果您需要您的程序依赖于任意值,则应将它们作为输入参数(在构造函数或方法中)接收,以便您在创建时有机会根据自己的意愿设置它们的值测试。这种重构会消耗开发时间,但您的代码会变得更干净、更安全。

相反,如果您拒绝重构代码,“按原样”运行测试的唯一方法是在调用 JVM 时设置系统属性值:

java -DMyField=... foo.bar.MyTest

关于java - 使用系统属性中的静态最终字段进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50950431/

相关文章:

java - 无法使用 ServletFileUpload 上传 100MB 文件

java - 如何组织在各个类(class)重复的对象? java

java - Mockito - 返回通用类型(多个)

unit-testing - 测试函数是否在 Scala 的给定范围内被调用

java - 使用日期值迭代 JSON 对象

java - 如何使用 Cobra/Lobo HTML 渲染器访问 DOM 节点的 CSS 属性

设置 Nimbus LookandFeel 后,Java Swing JOptionPane Yes 和 No Button 的字体大小不同

java - 我需要在测试前在 junit 中运行一次初始化代码 - java

java - Spring 启动测试: Unable to instantiate inner configuration class

gradle - 如何获取gradle和Junit5以使用名为* Should的测试类?