title: org.mockito.exceptions.misusing.WrongTypeOfReturnValue while stubbing a function from a "spy" object with mockito in groovy
body: <p>I'm having this issue which has taken enough time from me so I decided to ask the experts here.
  Some context.. I have a Jenkins shared library which with some groovy classes and I'm writing some unit tests using the <a href="https://github.com/jenkinsci/JenkinsPipelineUnit" rel="nofollow noreferrer">JenkinsPipelineUnit</a> framework. I'm using normal junit for testing so nothing special there.
  Basically I have a groovy class as following:</p>
  <pre><code>class MyClass {
      // In reality, `run` is object from the final class WorkflowRun but in the tests, I pass here a dummy map with the important fields
      def run
  
      MyClass(def run) {
          this.run = run
      }
  
      boolean somethingExists() {
          // some code here that does some stuff on `run` and return a boolean
      }
  
      String doSomething() {
          if(somethingExists()) {
              // do something with it.
              return &quot;foo&quot;
          } else {
              // do something else
              return &quot;bar&quot;
          }
      }
  }
  </code></pre>
  <p>The code above is simple enough and I am writing the following test for the <code>doSomething()</code> function without having to mock all the internals of <code>somethingExists()</code>.</p>
  <pre><code>@Test
  void testDoSomething() {
      Map run = [number: 1]
      MyClass mc = spy(new MyClass(run))
      // The problem is with the next line.
      doReturn(true).when(mc).somethingExists()
  
      assertTrue(mc.somethingExists())
      assertEquals(&quot;foo&quot;, mc.doSomething())
  }
  </code></pre>
  <p>Note that I cannot mock the <code>WorkflowRun</code> class since it is a final class and honestly I don't care about it since I need to test the logic inside <code>doSomething()</code> rather than what <code>somethingExists()</code> does which is checking some Jenkins internals on the <code>run</code> object. Therefore, I decided to &quot;spy&quot; on the object under test <code>mc</code> and make it return a simple <code>true</code> or <code>false</code> when I call <code>somethingExists()</code> to avoid too much mocking of the run object.
  According to Mockito's documentation, when I use the spy function, I should use the stubbing format like I did <code>doReturn(true).when(mc).somethingExists()</code> unlike the other format of <code>when(mc.somethingExists()).thenReturn(true)</code> since this will actually call the real function on the class while attempting to stub it.</p>
  <p><strong>Error message:</strong>
  When I call the <code>doReturn(true).when(mc).somethingExists()</code> I get the following error</p>
  <pre><code>org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
  Boolean cannot be returned by getMetaClass()
  getMetaClass() should return MetaClass
  ***
  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 org.codehaus.groovy.runtime.callsite.CallSiteArray.createPogoSite(CallSiteArray.java:140)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:158)
      at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
      at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
      at MyClassTest.testDoSomething(MyClassTest.groovy:37)
  ...
  </code></pre>
  <p>Note that I'm not running tests in parallel (actually while reproducing the issue, I was running only this test) and I'm following the stubbing rule suggested.
  At first I thought it is because of the <code>doReturn(true)</code> which is returning a primitive type instead of an object so I replaced it with <code>doReturn(Boolean.FALSE)</code> but I still got the same error.
  When I replace the line <code>doReturn(true).when(mc).somethingExists()</code> with <code>when(mc.somethingExists()).thenReturn(true)</code> then it fails because it is calling the real function <code>mc.somethingExists()</code> which is expected in my opinion. On the other hand, when I replace the entire content of the <code>somethingExists()</code> function with a simple <code>return false</code>, surprisingly, the format <code>doReturn(true).when(mc).somethingExists()</code> still failed however the other format <code>when(mc.somethingExists()).thenReturn(true)</code> worked which I'm surprised because this format should not work for spy objects.</p>
  <p>Any clues what I might be doing wrong? I have spent a lot of time trying to find the problem.
  Thanks in advance.</p>