抛出UncheckedIOException而不是其他预期的异常

时间:2017-09-05 19:59:14

标签: java oop exception refactoring cactoos

在重构Rultor以使用Cactoos代替Guava时,我遇到了GithubProfileTestGithubProfileValidationTest的否定测试问题。

在重构之后,正面测试用例通过了两个提到的测试类,但是期望特定异常的负面测试用例失败了。 受测试的重构代码是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无法评估,或者&#34;隐藏&#34;,这是对this.asset方法的调用引发的异常,引发了UncheckedIOException,所以我&# 39; m无法解决这个问题,并且Profile.ConfigException被提升了。

调试时,UncheckedIOException不包含任何Profile.ConfigException被提出的信息。

有关我为什么会遇到此行为或可能的解决方案的任何提示?

2 个答案:

答案 0 :(得分:3)

原因可能是在迭代填充地图时在org.cactoos.func.UncheckedFunc中完成转换。

由于函数式编程通常不能很好地处理异常,因此API会尝试避免声明已检查的异常。所以你可能不得不忍受这个。

答案 1 :(得分:3)

问题是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);
}
相关问题