Java 模拟系统类以获取系统属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20404276/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mock System class to get system properties
提问by sailaja.vellanki
I have a folder path set in system variable through JVM arguments in Eclipse and I am trying to access it in my class as:
System.getProperty("my_files_path")
.
我不得不通过在Eclipse的JVM参数系统变量的文件夹路径设置,我试图访问它在我的课为:
System.getProperty("my_files_path")
。
While writing junit test method for this class, I tried mocking this call as test classes do not consider JVM arguments. I have used PowerMockito to mock static System class and tried returning some path when System.getProperpty
is being called.
在为此类编写 junit 测试方法时,我尝试模拟此调用,因为测试类不考虑 JVM 参数。我使用 PowerMockito 模拟静态 System 类并尝试System.getProperpty
在调用时返回一些路径。
Had @RunWith(PowerMockRunner.class)
and @PrepareForTest(System.class)
annotations at class level. However, System class is not getting mocked as a result I always get null result.
Any help is appreciated.
曾@RunWith(PowerMockRunner.class)
与@PrepareForTest(System.class)
在类级别的注解。但是,系统类并没有被嘲笑,因为我总是得到空结果。任何帮助表示赞赏。
回答by Matt Lachman
There are certain classes PowerMock can't mock in the usual way. See here:
PowerMock 不能以通常的方式模拟某些类。看这里:
This, however, may still not work. In order of "good design" preference, you can fall back to these:
但是,这可能仍然不起作用。按照“良好设计”偏好的顺序,您可以回退到这些:
Refactor your code!Using a System property for passing a file path around is probably not the best way. Why not use a properties file loaded into a Properties object? Why not use getters/setters for the components that need to know this path? There are many better ways to do this.
The only reason I could think of notto do this is you're trying to wrap a test harness around code you "can't" modify.
Use
@Before
and@After
methods to set the System property to some known value for the test(s). You could even make it part of the@Test
method itself. This will be FAR easier than attempting to mock through PowerMock. Just callSystem.setProperty("my_files_path","fake_path");
重构你的代码!使用 System 属性来传递文件路径可能不是最好的方法。为什么不使用加载到 Properties 对象中的属性文件?对于需要知道此路径的组件,为什么不使用 getter/setter?有很多更好的方法可以做到这一点。
我能想到的不这样做的唯一原因是你试图围绕你“不能”修改的代码包装一个测试工具。
使用
@Before
和@After
方法将 System 属性设置为测试的某个已知值。您甚至可以将其作为@Test
方法本身的一部分。这比尝试通过 PowerMock 进行模拟要容易得多。打电话就行System.setProperty("my_files_path","fake_path");
回答by geddamsatish
@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"));
}
}
回答by sailaja.vellanki
Thanks Satish. This works except with a small modification. I wrote PrepareForTest(PathFinder.class), preparing the class I am testing for test cases instead of System.class
谢谢萨蒂什。除了小的修改外,这有效。我写了 PrepareForTest(PathFinder.class),准备了我正在测试的测试用例类而不是 System.class
Also, as mock works only once, I called my method right after mocking. My code just for reference:
此外,由于模拟只工作一次,我在模拟后立即调用了我的方法。我的代码仅供参考:
@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());
}
}
回答by geddamsatish
Sailaja add System.class because as per the power mock guidelines for static,private mocking you should add the class in prepare for test.
Sailaja 添加 System.class 因为根据静态、私有模拟的电源模拟指南,您应该在准备测试时添加该类。
@PrepareForTest({PathInformation.class,System.class})
Hope this helps.let me know if it doesn't work
希望这会有所帮助。如果它不起作用,请告诉我
回答by Stefan Birkner
Set the system property in your test and ensure that it is restored after the test by using the rule RestoreSystemPropertiesof the library System Rules.
在您的测试中设置系统属性,并确保在测试后通过使用库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());
}
}
回答by ekcrisp
System class is declared as final and cannot be mockedby libraries such as PowerMock. Several answers posted here are incorrect. If you are using Apache System Utilsyou can use getEnvironmentVariable
method instead of calling System.getenv directly. SystemUtils can be mocked since it is not declared as final.
System 类被声明为 final 并且不能被诸如 PowerMock 之类的库模拟。此处发布的几个答案不正确。如果您使用的是Apache System Utils,您可以使用getEnvironmentVariable
method 而不是直接调用 System.getenv。SystemUtils 可以被模拟,因为它没有被声明为 final。