模拟系统类来获取系统属性

问题描述 投票:0回答:8

我在 Eclipse 中通过 JVM 参数在系统变量中设置了一个文件夹路径,我尝试在我的类中访问它,如下所示:

System.getProperty("my_files_path")

在为此类编写 junit 测试方法时,我尝试模拟此调用,因为测试类不考虑 JVM 参数。我已经使用 PowerMockito 来模拟静态系统类,并尝试在调用

System.getProperpty
时返回一些路径。

在类级别有

@RunWith(PowerMockRunner.class)
@PrepareForTest(System.class)
注释。然而,系统类没有被嘲笑,因此我总是得到空结果。 任何帮助表示赞赏。

java mocking environment-variables system powermock
8个回答
16
投票

谢谢萨蒂什。除非稍作修改,否则此方法有效。我编写了PrepareForTest(PathFinder.class),准备我正在测试测试用例的类,而不是System.class

此外,由于模拟只能运行一次,因此我在模拟后立即调用了我的方法。 我的代码仅供参考:

@RunWith(PowerMockRunner.class)
@PrepareForTest(PathInformation.class)
public class PathInformationTest {

    private PathFinder pathFinder = new PathFinder();

@Test
    public void testValidHTMLFilePath() { 
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getProperty("my_files_path")).thenReturn("abc");
        assertEquals("abc",pathFinder.getHtmlFolderPath());
    }
}

8
投票

PowerMock 无法以通常的方式模拟某些类。请看这里:

然而,这可能仍然行不通。按照“良好设计”偏好的顺序,您可以选择以下这些:

  1. 重构您的代码!使用系统属性来传递文件路径可能不是最好的方法。为什么不使用加载到 Properties 对象中的属性文件?为什么不为需要知道该路径的组件使用 getter/setter?有很多更好的方法可以做到这一点。

    我能想到这样做的唯一原因是你试图将测试工具包装在你“无法”修改的代码周围。

  2. 使用

    @Before
    @After
    方法将系统属性设置为测试的某个已知值。您甚至可以将其作为
    @Test
    方法本身的一部分。这比尝试通过 PowerMock 进行模拟要容易得多。只需拨打电话
    System.setProperty("my_files_path","fake_path");


7
投票

System 类被声明为 Final,不能被 PowerMock 等库模拟。这里发布的几个答案是不正确的。如果您使用 Apache System Utils,您可以使用

getEnvironmentVariable
方法而不是直接调用 System.getenv。 SystemUtils 可以被模拟,因为它没有声明为最终的。


5
投票

在测试中设置系统属性,并确保在测试后使用库System Rules的规则RestoreSystemProperties恢复它。

public class PathInformationTest {
  private PathFinder pathFinder = new PathFinder();

  @Rule
  public TestRule restoreSystemProperties = new RestoreSystemProperties();

  @Test
  public void testValidHTMLFilePath() { 
    System.setProperty("my_files_path", "abc");
    assertEquals("abc",pathFinder.getHtmlFolderPath());
  }
}

1
投票

System.setter 或 getter 方法应放入用户定义的方法中,并且可以模拟该方法以在单元测试中返回所需的属性。

public String getSysEnv(){
return System.getEnv("thisprp");
}

0
投票

对我有用的唯一解决方案是将属性包装到 getter 方法中并在测试中模拟 getter。 PowerMockito 和其他人不适合我。


-1
投票
@RunWith(PowerMockRunner.class)
@PrepareForTest(System.class)
public class MySuperClassTest {   
@Test
public void test(){ 
    PowerMockito.mockStatic(System.class);
    PowerMockito.when(System.getProperty("java.home")).thenReturn("abc");
    System.out.println(System.getProperty("java.home"));
}
} 

-1
投票

Sailaja 添加 System.class,因为根据静态、私有模拟的强大模拟指南,您应该添加该类以准备测试。

 @PrepareForTest({PathInformation.class,System.class})

希望这有帮助。如果不起作用请告诉我

© www.soinside.com 2019 - 2024. All rights reserved.