在将Rultor重构为使用Cactoos而不是Guava时,我对 GithubProfileTest GithubProfileValidationTest的否定测试存在问题。

重构之后,肯定的测试用例通过了上述两个测试类,但是期望特定异常的否定的测试用例失败了。
受测试的受影响的重构代码是GithubProfile.assets方法和GithubProfile.asset方法。

我重构了assets方法,如下所示:

 public Map<String, InputStream> assets() throws IOException {
    final XML xml = this.read();
    final List<XML> nodes = xml.nodes("/p/entry[@key='assets']/entry");
    return new MapOf<>(
        new Mapped<>(
            nodes,
            input ->
                new MapEntry<>(
                    input.xpath("@key").get(0),
                    this.asset(input.xpath("text()").get(0))
                )
        )
    );
}

在不同的测试用例中,预期this.asset调用会抛出Profile.ConfigException。相反,在调用assets方法时,测试失败,并显示Unable to evaluate the expression Method threw 'java.io.UncheckedIOException' exception,并且Profile.ConfigException只是被忽略/隐藏。

似乎MapOf某种程度上无法评估或“隐藏”异常,该异常是对this.asset方法的调用引发的,它本身引发了UncheckedIOException,因此我无法解决此问题,并引发了Profile.ConfigException

调试时,UncheckedIOException不包含任何引发Profile.ConfigException的信息。

关于为什么我可能会得到这种行为或可能的解决方案的任何提示?

最佳答案

问题是Iterable#next()(在JDK中)不允许引发检查的异常(例如Profile.ConfigException)。这就是org.cactoos.iterator.Mapped将它们全部捕获并改为抛出UncheckedIOException的原因。由于JDK的设计,它是无法修复的。您可以做的最好的事情就是旧的for循环:

public Map<String, InputStream> assets() throws IOException {
  final XML xml = this.read();
  final List<XML> nodes = xml.nodes("/p/entry[@key='assets']/entry");
  final List<MapEntry> entries = new LinkedList<>();
  for (final XML node : nodes) {
    entries.add(
      new MapEntry<>(
        input.xpath("@key").get(0),
        this.asset(input.xpath("text()").get(0)) // checked exeption here
      )
    );
  }
  return new MapOf<>(entries);
}

09-26 15:09