我的流程只是将一些内容添加到系统变量PATH
。实际上,我正在使用Process
使用setx.exe
:
public void changePath(String newPath ) {
String path = System.getenv("PATH") + ";";
String[] cmd = new String[]{"C:\\Windows\\System32\\setx.exe", "PATH",
path+newPath, "-m"};
ProcessBuilder builder = new ProcessBuilder(cmd);
...
}
所以我试着给它写一个测试用例。
Class UpdatePathTest {
@Test
public void testUpdatePath() {
//call the method that update the path
changePath("C:\\somebin");
assertTrue(System.getenv("PATH").contains("C:\\somebin")); //fails
// ProcessBuilder with command String[]{"cmd", "/C", "echo", "%PATH%"}; will fail too.
//and the above in a new Thread will fail too.
}
}
那么,有没有办法获得新的PATH值?编写新路径是唯一的选择,因为我正在开发一个将安装桌面应用程序的jar。
答案 0 :(得分:1)
我不确定在单元测试中改变路径是个好主意。如果测试失败怎么办?你必须确保你做了所有相关的整理。
考虑反转依赖关系并使用依赖注入。
This文章解释得很清楚。
所以不要有一个方法:
public void method() {
String path = System.getenv("PATH") + ";";
//do stuff on path
}
考虑做:
public void method(String path) {
//do stuff on path
}
允许您存根路径。如果您无法更改方法的签名,请考虑使用工厂模式并使用测试工厂来获取路径。
你需要考虑的是你正在测试的内容。当您调用C:\ Windows \ System32 \ setx.exe时,您已阅读API文档并使用正确的参数调用它。这很像在java API上调用另一个方法。例如,如果您正在操作列表,则“知道”它基于零。你不需要测试这个,你只需阅读API,社区支持你。为了测试changePath,我想你可能会测试什么进入ProcessBuilder。您再次阅读了API文档,并且您必须假设您正在传递正确的变量。 (参见底部的// 1)再次,您必须假设ProcessBuilder正常工作,并且Oracle(或者很可能是Sun)的人已经将它实现到API文档中。
所以你要做的就是检查你是否正在将变量传递给符合规范的ProcessBuilder。为此,您可以模拟ProcessBuilder,然后验证您是否正在传递正确的参数并在此类上调用正确的方法。
一般来说,测试很难,因为你不想测试windows函数,但想测试java与它们的交互。
// 1调用此外部命令时遇到的主要问题是正确理解API文档或设置命令。通常,您必须获取命令行并检查您是否正确使用方法(esp cmd函数)。这可能意味着您要弄清楚如何使用cmd函数,将其编码到ProcessBuilder中然后编写测试(反之亦然,在ProcessBuilder / test上)不是理想的方法,但有时文档很难理解。