37

MyCustomExceptionタイプの例外がスローされることを確認するいくつかの JUnit テストを作成しています。ただし、この例外は他の例外に何度もラップされます。たとえば、InvocationTargetException にラップされ、それがさらに RuntimeException にラップされます。

MyCustomException が実際にキャッチした例外を何らかの形で引き起こしたかどうかを判断する最善の方法は何ですか? 私はこのようなことをしたいと思います(下線を参照):


try {
    doSomethingPotentiallyExceptional();
    fail("Expected an exception.");
} catch (RuntimeException e) {
     if (!e.原因となった(MyCustomException.class)
        fail("Expected a different kind of exception.");
}

いくつかの「レイヤー」を深く呼び出すことgetCause()や、同様の醜い回避策を避けたいと思います。より良い方法はありますか?

(明らかに、Spring にはNestedRuntimeException.contains(Class)があり、これは私が望むことを行いますが、Spring は使用していません。)

CLOSED: わかり ました、ユーティリティ メソッドを回避する方法は本当にないと思います :-) 返信してくださった皆さんに感謝します!

4

9 に答える 9

44

Apache Commons Langを使用している場合は、次を使用できます。

(1) 原因が正確に特定されたタイプである必要がある場合

if (ExceptionUtils.indexOfThrowable(exception, ExpectedException.class) != -1) {
    // exception is or has a cause of type ExpectedException.class
}

(2) 原因が特定のタイプまたはそのサブクラスのタイプのいずれかである必要がある場合

if (ExceptionUtils.indexOfType(exception, ExpectedException.class) != -1) {
    // exception is or has a cause of type ExpectedException.class or its subclass
}
于 2015-03-25T10:17:09.620 に答える
6

getCause のレイヤーを介して呼び出す以外に選択肢はないと思います。あなたが言及したSpring NestedRuntimeExceptionのソースコードを見ると、それがどのように実装されているかがわかります。

于 2009-03-04T13:59:54.477 に答える
2

模倣は、お世辞の最も誠実な形です。 source の簡単な調査に基づいて、これはまさに NestedRuntimeException が行うことです:

/**
 * Check whether this exception contains an exception of the given type:
 * either it is of the given class itself or it contains a nested cause
 * of the given type.
 * @param exType the exception type to look for
 * @return whether there is a nested exception of the specified type
 */
public boolean contains(Class exType) {
    if (exType == null) {
        return false;
    }
    if (exType.isInstance(this)) {
        return true;
    }
    Throwable cause = getCause();
    if (cause == this) {
        return false;
    }
    if (cause instanceof NestedRuntimeException) {
        return ((NestedRuntimeException) cause).contains(exType);
    }
    else {
        while (cause != null) {
            if (exType.isInstance(cause)) {
                return true;
            }
            if (cause.getCause() == cause) {
                break;
            }
            cause = cause.getCause();
        }
        return false;
    }
}

注意: 上記は 2009 年 3 月 4 日時点のコードです。したがって、Spring が現在何を行っているかを本当に知りたい場合は、現在存在するコードを調査する必要があります (いつでも)。

于 2009-03-04T14:32:14.807 に答える
1

グアバを使用してこれを行うことができます:

FluentIterable.from(Throwables.getCausalChain(e))
                        .filter(Predicates.instanceOf(ConstraintViolationException.class))
                        .first()
                        .isPresent();
于 2014-07-21T18:41:26.760 に答える