/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.citrus.test; import static org.hamcrest.Matchers.*; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; /** * 用来检查一个异常的类型和message内容。 * * @author Michael Zhou */ public class ExceptionMatcher<T extends Throwable> extends BaseMatcher<T> { private final Matcher<?> exceptionMatcher; private final Matcher<?> causeExceptionMatcher; private final Matcher<?> messageMatcher; private final Class<? extends Throwable> cause; public ExceptionMatcher(String... snippets) { this(null, snippets); } public ExceptionMatcher(Class<? extends Throwable> cause, String... snippets) { // exception matcher List<Matcher<?>> matchers = new LinkedList<Matcher<?>>(); matchers.add(notNullValue()); matchers.add(instanceOf(Throwable.class)); exceptionMatcher = allOf(matchers); // cause exception matcher if (cause != null) { matchers = new LinkedList<Matcher<?>>(); matchers.add(notNullValue()); matchers.add(instanceOf(cause)); causeExceptionMatcher = allOf(matchers); } else { causeExceptionMatcher = null; } this.cause = cause; // message exception matcher if (snippets != null && snippets.length > 0) { matchers = new LinkedList<Matcher<?>>(); for (String snippet : snippets) { matchers.add(containsString(snippet)); } messageMatcher = allOf(matchers); } else { messageMatcher = null; } } public boolean matches(Object item) { if (!exceptionMatcher.matches(item)) { return false; } Throwable top = (Throwable) item; Throwable t = top; if (causeExceptionMatcher != null) { Set<Throwable> visited = new HashSet<Throwable>(); for (; t != null && !cause.isInstance(t) && !visited.contains(t); t = t.getCause()) { visited.add(t); } if (!causeExceptionMatcher.matches(t)) { return false; } } if (messageMatcher == null) { return true; } else { String message = t.getMessage(); if (t != top) { message += "\n" + top.getMessage(); } return messageMatcher.matches(message); } } public void describeTo(Description description) { description.appendText("An exception that is ").appendDescriptionOf(exceptionMatcher); if (causeExceptionMatcher != null) { description.appendText("\n and its cause exception is ").appendDescriptionOf(causeExceptionMatcher); } if (messageMatcher != null) { description.appendText("\n and its message is ").appendDescriptionOf(messageMatcher); } } }