匹配自定义异常
Matching custom exceptions
Javadoc 为 matches
方法给出了这个例子:
assertThat(player).matches(p -> p.isRookie());
确实,当我定义一个虚拟 class Player 时,上面的语句编译正常。但是,当我定义一个派生自 Exception 的 class 时,以下内容不会编译:
public class MyCustomException extends Exception {
public boolean isMyCustomFieldSet() { return true; }
}
...
MyCustomException myCustomException = new MyCustomExcpetion();
assertThat(myCustomException).matches(e -> e.isMyCustomFieldSet());
我可以使用强制转换使其编译:
assertThat(myCustomException).matches(e -> ((MyCustomException)e).isMyCustomFieldSet());
但该演员表看起来 "ugly" 并且有点破解以解决某种缺陷。我可以让它以 "nicer" 方式编译,即不使用强制转换吗?
我认为你找不到更短的路。
问题是
assertThat(new Player())
returns 一个 ObjectAssert<Player>
,其 matches
签名为 matches(Predicate<? super Player>)
。
然而,
assertThat(new MyException())
实际上调用了一个不同的方法 assertThat
,其中 returns 一个 AbstractThrowableAssert<?, ? extends Throwable>
和一个 matches(Predicate<? super Throwable>)
.
这就解释了问题,但我无法为您提供更好的解决方法。
我还没有检查是否存在针对它的未解决问题,但如果不存在,可能值得提交一个。
据我所知,无法直接使用方法 isMyCustomFieldSet。因为使用泛型 class 和泛型 class 的断言库不能直接或间接扩展 Throwable class。
More info here
问题出在 Assertions
,它声明 AbstractThrowableAssert<?, ? extends Throwable> assertThat(Throwable t)
而不是 <T> AbstractThrowableAssert<?, T extends Throwable> assertThat(T t)
但不幸的是,由于以下现有方法与之冲突,因此无法完成此操作:public static <T> ObjectAssert<T> assertThat(T actual)
。
铸造是一种解决方案,我同意它不是超级优雅。
在那种情况下我会做的很简单:
assertThat(myCustomException.isMyCustomFieldSet()).isTrue();
或直接对 myCustomException
进行断言:
assertThat(myCustomException).hasFieldOrPropertyWithValue("myCustomFieldSet", true)
.hasFieldOrPropertyWithValue("myOtherField", "foo");
这里的缺点是按名称访问字段,这对重构不友好。
Javadoc 为 matches
方法给出了这个例子:
assertThat(player).matches(p -> p.isRookie());
确实,当我定义一个虚拟 class Player 时,上面的语句编译正常。但是,当我定义一个派生自 Exception 的 class 时,以下内容不会编译:
public class MyCustomException extends Exception {
public boolean isMyCustomFieldSet() { return true; }
}
...
MyCustomException myCustomException = new MyCustomExcpetion();
assertThat(myCustomException).matches(e -> e.isMyCustomFieldSet());
我可以使用强制转换使其编译:
assertThat(myCustomException).matches(e -> ((MyCustomException)e).isMyCustomFieldSet());
但该演员表看起来 "ugly" 并且有点破解以解决某种缺陷。我可以让它以 "nicer" 方式编译,即不使用强制转换吗?
我认为你找不到更短的路。
问题是
assertThat(new Player())
returns 一个 ObjectAssert<Player>
,其 matches
签名为 matches(Predicate<? super Player>)
。
然而,
assertThat(new MyException())
实际上调用了一个不同的方法 assertThat
,其中 returns 一个 AbstractThrowableAssert<?, ? extends Throwable>
和一个 matches(Predicate<? super Throwable>)
.
这就解释了问题,但我无法为您提供更好的解决方法。
我还没有检查是否存在针对它的未解决问题,但如果不存在,可能值得提交一个。
据我所知,无法直接使用方法 isMyCustomFieldSet。因为使用泛型 class 和泛型 class 的断言库不能直接或间接扩展 Throwable class。 More info here
问题出在 Assertions
,它声明 AbstractThrowableAssert<?, ? extends Throwable> assertThat(Throwable t)
而不是 <T> AbstractThrowableAssert<?, T extends Throwable> assertThat(T t)
但不幸的是,由于以下现有方法与之冲突,因此无法完成此操作:public static <T> ObjectAssert<T> assertThat(T actual)
。
铸造是一种解决方案,我同意它不是超级优雅。
在那种情况下我会做的很简单:
assertThat(myCustomException.isMyCustomFieldSet()).isTrue();
或直接对 myCustomException
进行断言:
assertThat(myCustomException).hasFieldOrPropertyWithValue("myCustomFieldSet", true)
.hasFieldOrPropertyWithValue("myOtherField", "foo");
这里的缺点是按名称访问字段,这对重构不友好。