| /* |
| * Copyright (c) 2007 Mockito contributors |
| * This program is made available under the terms of the MIT License. |
| */ |
| package org.mockito.internal.stubbing.answers; |
| |
| import java.io.Serializable; |
| import java.lang.reflect.Modifier; |
| import org.mockito.invocation.InvocationOnMock; |
| import org.mockito.stubbing.Answer; |
| import org.mockito.stubbing.ValidableAnswer; |
| |
| import static org.mockito.Answers.RETURNS_DEFAULTS; |
| import static org.mockito.internal.exceptions.Reporter.cannotCallAbstractRealMethod; |
| |
| /** |
| * Optional Answer that adds partial mocking support |
| * <p> |
| * {@link Answer} can be used to define the return values of unstubbed invocations. |
| * <p> |
| * This implementation can be helpful when working with legacy code. |
| * When this implementation is used, unstubbed methods will delegate to the real implementation. |
| * This is a way to create a partial mock object that calls real methods by default. |
| * <p> |
| * As usual you are going to read <b>the partial mock warning</b>: |
| * Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects. |
| * How does partial mock fit into this paradigm? Well, it just doesn't... |
| * Partial mock usually means that the complexity has been moved to a different method on the same object. |
| * In most cases, this is not the way you want to design your application. |
| * <p> |
| * However, there are rare cases when partial mocks come handy: |
| * dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.) |
| * However, I wouldn't use partial mocks for new, test-driven & well-designed code. |
| * <p> |
| */ |
| public class CallsRealMethods implements Answer<Object>, ValidableAnswer, Serializable { |
| private static final long serialVersionUID = 9057165148930624087L; |
| |
| public Object answer(InvocationOnMock invocation) throws Throwable { |
| if (Modifier.isAbstract(invocation.getMethod().getModifiers())) { |
| return RETURNS_DEFAULTS.answer(invocation); |
| } |
| return invocation.callRealMethod(); |
| } |
| |
| @Override |
| public void validateFor(InvocationOnMock invocation) { |
| if (new InvocationInfo(invocation).isAbstract()) { |
| throw cannotCallAbstractRealMethod(); |
| } |
| } |
| } |