在将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);
}