我正在尝试验证我的所有异常都是正确的。因为值包含在CompletableFutures
中,抛出的异常是ExecutionException
,因为我通常会检查异常。快速举例:
void foo() throws A {
try {
bar();
} catch B b {
throw new A(b);
}
}
所以foo()
会翻译bar()
引发的异常,所有这些都是在CompletableFutures
和AsyncHandlers
内完成的(我不会复制整个代码,只是为了参考)
在我的单元测试中,我正在使bar()
抛出异常并想要在调用foo()
时检查它是否已正确翻译:
Throwable b = B("bleh");
when(mock.bar()).thenThrow(b);
ExpectedException thrown = ExpectedException.none();
thrown.expect(ExecutionException.class);
thrown.expectCause(Matchers.allOf(
instanceOf(A.class),
having(on(A.class).getMessage(),
CoreMatchers.is("some message here")),
));
到目前为止一切顺利,但我还想验证异常原因A
是异常B
而having(on(A.class).getCause(), CoreMatchers.is(b))
导致CodeGenerationException --> StackOverflowError
TL; DR:我如何得到预期异常原因?
答案 0 :(得分:3)
也许您应该尝试使用简单的hasProperty匹配器来解决问题:
thrown.expectCause(allOf(
instanceOf(A.class),
hasProperty("message", is("some message here")),
));
答案 1 :(得分:0)
这是我用来测试因果类链的一个例子。 参考文献:
import static org.hamcrest.Matchers.contains;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class CausalClassChainTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void test() throws Exception {
expectedException.expect(IOException.class);
expectedException.expectCause(new CausalClassChainMather(Exception.class, RuntimeException.class));
throw new IOException(new Exception(new RuntimeException()));
}
private static class CausalClassChainMather extends TypeSafeMatcher<Throwable> {
private final Class<? extends Throwable>[] expectedClasses;
private List<Class<? extends Throwable>> causualClasses;
private Matcher<Iterable<? extends Class<? extends Throwable>>> matcher;
public CausalClassChainMather(Class<? extends Throwable>... classes) {
this.expectedClasses = classes;
}
@Override
public void describeTo(Description description) {
// copy of MatcherAssert.assertThat()
description.appendText("")
.appendText("\nExpected: ")
.appendDescriptionOf(matcher)
.appendText("\n but: ");
matcher.describeMismatch(causualClasses, description);
}
@Override
protected boolean matchesSafely(Throwable item) {
List<Class<? extends Throwable>> causes = new ArrayList<Class<? extends Throwable>>();
while (item != null) {
causes.add(item.getClass());
item = item.getCause();
}
causualClasses = Collections.unmodifiableList(causes);
// ordered test
matcher = contains(expectedClasses);
return matcher.matches(causualClasses);
}
}
}
答案 2 :(得分:0)
尝试类似,以查明原因:
thrown.expectCause(allOf(
isA(org.apache.kafka.common.errors.SerializationException.class),
hasProperty("message", containsString("Error deserializing Avro message for id")),
hasProperty("cause", allOf(
isA(org.apache.avro.AvroTypeException.class),
hasProperty("message", containsString("missing required field blabla"))
))
));