0

我的过程只是简单地向系统变量添加一些内容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。

4

1 回答 1

1

我不确定在单元测试中更改路径是否是个好主意。如果测试失败怎么办?您必须确保完成所有相关的整理工作。

考虑反转你的依赖并使用依赖注入。

我认为这篇文章解释得很好。

因此,而不是有一个方法:

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 文档或设置命令。通常你必须拿出命令行并检查你是否正确使用了方法(尤其是 cmd 函数)。这可能意味着您要弄清楚如何使用 cmd 函数,将其编码到 ProcessBuilder 中,然后在 ProcessBuilder/test 上编写测试(反之亦然) 这不是理想的方式,但有时文档很难理解。

于 2012-09-03T18:48:00.377 回答