title: Mockito - stub abstract parent class method
body: <p>I am seeing very strange behavior trying to stub a method <code>myMethod(param)</code> of class <code>MyClass</code> that is defined in an abstract parent class <code>MyAbstractBaseClass</code>.</p>
  <p>When I try to stub (using <code>doReturn(&quot;...&quot;).when(MyClassMock).myMethod(...)</code> etc.) this method fails, different exceptions are thrown under different scenarios. The exceptions are thrown right on that line.</p>
  <p>When I use  <code>doReturn(&quot;...&quot;).when(MyClassMock).myMethod(CONCRETE PARAM CLASS OBJECT)</code>, I get the following exception:</p>
  <pre><code>org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
  String cannot be returned by hasValidExpirationDate()
  hasValidExpirationDate() should return boolean
      at ...
  </code></pre>
  <p><strong><code>hasValidExpirationDate()</code> is not a method being stubbed, but it is called by the real implementation of <code>MyMethod(param)</code> in the abstract base class.</strong></p>
  <p>When I use  <code>doReturn(&quot;...&quot;).when(MyClassMock).myMethod(any(PARAMCLASS.class))</code>, I get the following exception:</p>
  <pre><code>org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
  Invalid use of argument matchers!
  0 matchers expected, 1 recorded.
  This exception may occur if matchers are combined with raw values:
  </code></pre>
  <p>, etc.</p>
  <p>But when I define the method <code>myMethod(param)</code> in a subclass <code>MyClass</code> the code no longer fails. My concrete implementation in <code>MyClass</code> just calls <code>super.myMethod(param)</code> and returns it, so it has no effect other than fixing the unit test. So it looks like Mockito can only stub methods defined in the class being mocked itself, not in the super classes.</p>
  <p>I am reading Mockito documentation and I don't see where it says that inherited methods can't be stubbed.</p>
  <p><code>myMethod(param)</code> is neither <code>static</code> nor <code>final</code>.</p>
  <h1>Code:</h1>
  <p>Class <code>BaseCard</code>:</p>
  <pre><code>import java.io.Serializable;
  
  public class BaseCard implements Serializable {
  
      public boolean hasValidExpirationDate() {
          return true;
      }
  }
  </code></pre>
  <p>Class <code>Card</code>:</p>
  <pre><code>abstract class Card  extends BaseCard {
  
      public Card () {    }
  
      public String getUnexpiredStringForNetwork(){
  
          //If the date is invalid return empty string, except for Discover.
          if( ! hasValidExpirationDate()){
             return &quot;hi&quot;;
          }
  
          return &quot;hello&quot;;
      }
  }
  </code></pre>
  <p>Class <code>DecryptedCard</code>:</p>
  <pre><code>public class DecryptedCard extends Card {
  
  }
  </code></pre>
  <p>Class <code>MyTest</code>:</p>
  <pre><code>import static org.mockito.Mockito.doReturn;
  import static org.mockito.Mockito.mock;
  
  import org.junit.Test;
  
  
  public class MyTest {
  
      @Test
      public void test() {
          DecryptedCard decryptedCardMock = mock(DecryptedCard.class);
  
          doReturn(&quot;ABC&quot;).when(decryptedCardMock).getUnexpiredStringForNetwork();
  
      }
  
  }
  </code></pre>
  <p>Failure:</p>
  <pre><code>org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
  String cannot be returned by hasValidExpirationDate()
  hasValidExpirationDate() should return boolean
  ***
  If you're unsure why you're getting above error read on.
  Due to the nature of the syntax above problem might occur because:
  1. This exception *might* occur in wrongly written multi-threaded tests.
     Please refer to Mockito FAQ on limitations of concurrency testing.
  2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - 
     - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
  
      at Card.getUnexpiredStringForNetwork(Card.java:10)
      at DecryptedCard.getUnexpiredStringForNetwork(DecryptedCard.java:1)
      at MyTest.test(MyTest.java:13)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
      at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
      at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
  </code></pre>