预期的异常是异常的根本原因吗?

8

我正在尝试验证所有异常是否正确。由于值被包装在 CompletableFuture 中,因此抛出的异常是带有原因的 ExecutionException,我通常会检查该异常。快速示例:

void foo() throws A {
  try {
    bar();
  } catch B b {
    throw new A(b);
  }
}

所以foo()翻译了由bar()抛出的异常,所有这些都在CompletableFuturesAsyncHandlers中完成(我不会复制整个代码,只是作为参考)

在我的单元测试中,我让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: 我如何获得预期异常的原因的原因?

也许这个问题是你想要的(我不确定):https://dev59.com/lnNA5IYBdhLWcg3wrP2q#20759785 - user180100
@RC。几乎了解,但我必须深入一层并获取下一个原因 :) - Amir
1
你应该能够适应:https://dev59.com/lnNA5IYBdhLWcg3wrP2q#6528640 - user180100
3个回答

4
也许您可以尝试使用简单的hasProperty Matcher来隔离问题:
thrown.expectCause(allOf(
                    instanceOf(A.class),
                    hasProperty("message", is("some message here")),
        ));

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

}

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"))
                    ))
            ));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接