1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.stubbing.answers; 6 7 import java.io.Serializable; 8 import org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter; 9 import org.mockito.internal.util.MockUtil; 10 import org.mockito.invocation.InvocationOnMock; 11 import org.mockito.stubbing.Answer; 12 import org.mockito.stubbing.ValidableAnswer; 13 14 import static org.mockito.internal.exceptions.Reporter.cannotStubWithNullThrowable; 15 import static org.mockito.internal.exceptions.Reporter.checkedExceptionInvalid; 16 17 /** 18 * An answer that always throws the same throwable. 19 */ 20 public class ThrowsException implements Answer<Object>, ValidableAnswer, Serializable { 21 22 private static final long serialVersionUID = 1128820328555183980L; 23 private final Throwable throwable; 24 private final ConditionalStackTraceFilter filter = new ConditionalStackTraceFilter(); 25 26 /** 27 * Creates a new answer always throwing the given throwable. If it is null, 28 * {@linkplain ValidableAnswer#validateFor(InvocationOnMock) answer validation} 29 * will fail. 30 */ ThrowsException(Throwable throwable)31 public ThrowsException(Throwable throwable) { 32 this.throwable = throwable; 33 } 34 answer(InvocationOnMock invocation)35 public Object answer(InvocationOnMock invocation) throws Throwable { 36 if (throwable == null) { 37 throw new IllegalStateException("throwable is null: " + 38 "you shall not call #answer if #validateFor fails!"); 39 } 40 if (MockUtil.isMock(throwable)) { 41 throw throwable; 42 } 43 Throwable t = throwable.fillInStackTrace(); 44 45 if (t == null) { 46 //Custom exceptions sometimes return null, see #866 47 throw throwable; 48 } 49 filter.filter(t); 50 throw t; 51 } 52 53 @Override validateFor(InvocationOnMock invocation)54 public void validateFor(InvocationOnMock invocation) { 55 if (throwable == null) { 56 throw cannotStubWithNullThrowable(); 57 } 58 59 if (throwable instanceof RuntimeException || throwable instanceof Error) { 60 return; 61 } 62 63 if (!new InvocationInfo(invocation).isValidException(throwable)) { 64 throw checkedExceptionInvalid(throwable); 65 } 66 } 67 } 68