ExpectedException原因的原因?

时间:2016-11-25 16:18:52

标签: java junit exception-handling hamcrest expected-exception

我正在尝试验证我的所有异常都是正确的。因为值包含在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:我如何得到预期异常原因?

3 个答案:

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