Mockito.doThrow 具有自定义堆栈跟踪

Mockito.doThrow with custom stacktrace

我正在尝试对需要我使用特定堆栈跟踪元素抛出异常的特定场景进行单元测试。

基本上我是这样的:

    final RuntimeException exception = new RuntimeException();
    exception.setStackTrace(
        new StackTraceElement[] {
            new StackTraceElement(
                Claims.class.getCanonicalName(),
                "add",
                "Claims.java",
                123
            )
        }
    );
    Mockito.doThrow(exception).when(stk).process(project, claim);

但在被测方法中抛出的异常不包含此元素,它包含单元测试的堆栈跟踪 class。

Mockito是否可以完全按照我的意愿抛出异常?或者它会始终覆盖堆栈跟踪吗?

抛出异常的行为将重写其堆栈跟踪,即使它是由 doThrow 完成的。 解决这个问题的一种方法是不使用真正的异常,而是模拟它:

RuntimeException exception = mock(RuntimeException.class);
when(exception.getStackTrace()).thenReturn(
    new StackTraceElement[] {
        new StackTraceElement(
            Claims.class.getCanonicalName(),
            "add",
            "Claims.java",
            123
        )
    }
);

另一种方法是使用 doAnswerthenAnswer 来抛出异常:

Mockito.doAnswer((invocation) -> {
    throw exception;
}).when(stk).process(project, claim);

这将使您的原始堆栈跟踪保持完整,而不是让 Mockito 破坏它。