获取系统属性的Mock System类

时间:2013-12-05 15:42:37

标签: mocking environment-variables system powermock getproperty

我在Eclipse中通过JVM参数在系统变量中设置了一个文件夹路径,我试图在我的类中访问它: System.getProperty("my_files_path")

在为这个类编写junit测试方法时,我尝试模拟这个调用,因为测试类不考虑JVM参数。我使用PowerMockito来模拟静态System类,并尝试在调用System.getProperpty时返回一些路径。

在班级有@RunWith(PowerMockRunner.class)@PrepareForTest(System.class)注释。但是,System类没有被模拟,因此我总是得到null结果。  任何帮助表示赞赏。

7 个答案:

答案 0 :(得分:12)

谢谢萨蒂什。除了小修改外,这个工作正常。我写了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());
    }
}

答案 1 :(得分:7)

某些类PowerMock无法以通常的方式进行模拟。见这里:

然而,这可能仍然无效。按照“良好设计”的优先顺序,你可以回到这些:

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

    我认为这样做的唯一原因是你试图围绕“无法”修改的代码包装测试工具。

  2. 使用@Before@After方法将System属性设置为测试的某个已知值。您甚至可以将其作为@Test方法本身的一部分。这比试图模拟PowerMock更容易。只需致电System.setProperty("my_files_path","fake_path");

  3. 即可

答案 2 :(得分:6)

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

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());
  }
}

答案 3 :(得分:6)

系统类被声明为最终类,不能被PowerMock之类的库模拟。这里发布的几个答案不正确。如果使用offline directline,则可以使用getEnvironmentVariable方法,而不是直接调用System.getenv。可以嘲笑SystemUtils,因为它没有声明为final。

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

@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"));
}
} 

答案 6 :(得分:0)

Sailaja添加了System.class,因为根据静态私有模拟的电源模拟指南,您应该在准备测试时添加该类。

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

希望这会有所帮助。我知道它是否有效