8

我正在尝试验证我的所有异常是否正确。因为值包含在 中CompletableFutures,所以抛出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是异常Bhaving(on(A.class).getCause(), CoreMatchers.is(b))原因CodeGenerationException --> StackOverflowError

TL;DR:我如何获得预期异常的原因?

4

3 回答 3

4

也许您应该尝试使用简单的hasProperty Matcher,以隔离问题:

thrown.expectCause(allOf(
                    instanceOf(A.class),
                    hasProperty("message", is("some message here")),
        ));
于 2016-11-26T17:28:04.317 回答
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);
        }
    }

}
于 2017-08-23T16:02:26.707 回答
0

Try sth like,以验证原因的原因:

    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"))
                    ))
            ));
于 2018-07-18T12:40:42.523 回答