在重构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
无法评估,或者&#34;隐藏&#34;,这是对this.asset方法的调用引发的异常,引发了UncheckedIOException
,所以我&# 39; m无法解决这个问题,并且Profile.ConfigException
被提升了。
调试时,UncheckedIOException
不包含任何Profile.ConfigException
被提出的信息。
有关我为什么会遇到此行为或可能的解决方案的任何提示?
答案 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);
}