title: Mockito cannot create Spy of @Autowired Spring-Data Repository
body: <p>I am trying to overlay my whole test environment with Mockito.spy functionality so whenever I want i can stub a method but all other calls go to default functionality.
  This worked very well with the Service layer but I have problems with the Repository layer.</p>
  
  <p>My setup is as follows:</p>
  
  <p>Mockito - 2.15.0
  Spring - 5.0.8
  SpringBoot - 2.0.4</p>
  
  <p>Repository:</p>
  
  <pre><code>public interface ARepository extends CrudRepository&lt;ADBO, Long&gt; {}
  </code></pre>
  
  <p>Service:</p>
  
  <pre><code>@Service
  public class AService {
  
      @Autowired
      ARepository aRepository;
  
      public ADBO getById(long id) {
          return aRepository.findById(id).orElse(null);
      }
  
      public Iterable&lt;ADBO&gt; getAll() {
          return aRepository.findAll();
      }
  }
  </code></pre>
  
  <p>The configuration for the spy:</p>
  
  <pre><code>@Profile("enableSpy")
  @Configuration
  public class SpyConfig {
  
      @Bean
      @Primary
      public ARepository aRepository() {
          return Mockito.spy(ARepository.class);
      }
  }
  </code></pre>
  
  <p>And my test class:</p>
  
  <pre><code>@ActiveProfiles("enableSpy")
  @RunWith(SpringRunner.class)
  @SpringBootTest
  public class AServiceTest {
  
      @Autowired
      AService aService;
  
      @Autowired
      ARepository aRepository;
  
      @Test
      public void test() {
          ADBO foo = new ADBO();
          foo.setTestValue("bar");
          aRepository.save(foo);
  
          doReturn(Optional.of(new ADBO())).when(aRepository).findById(1L);
          System.out.println("result (1):" + aService.getById(1));
  
          System.out.println("result all:" + aService.getAll());
  
      }
  }
  </code></pre>
  
  <p>Now there are three possible outcomes to this test:</p>
  
  <ul>
  <li>aRepository is neither a mock nor a spy:<br>
  <code>org.mockito.exceptions.misusing.NotAMockException: 
  Argument passed to when() is not a mock!
  Example of corr...</code></li>
  <li><p>aRepository is a mock but not a spy (this is the result I get):<br>
  <code>result (1):ADBO(id=null, testValue=null)
  result all:[]</code></p></li>
  <li><p>aRepository is a spy (this is what I want):<br>
  <code>result (1):ADBO(id=null, testValue=null)
  result all:[ADBO(id=1, testValue=bar)]</code></p></li>
  </ul>
  
  <p>I attribute this behavior to the fact that the spring instantiation of the repository is more complex in the background and the repository is not correctly instantiated when calling <code>Mockito.spy(ARepository.class)</code>.</p>
  
  <p>I have also tried autowireing the proper instance into the Configuration and calling <code>Mockito.spy()</code> with the @Autowired object.</p>
  
  <p>This results in:</p>
  
  <pre><code>Cannot mock/spy class com.sun.proxy.$Proxy75
  Mockito cannot mock/spy because :
   - final class
  </code></pre>
  
  <p>According to my research Mockito can mock and spy final classes since v2.0.0.</p>
  
  <p>Calling <code>Mockito.mockingDetails(aRepository).isSpy()</code> returns <code>true</code> which leads me to think the object in the background was not correctly instantiated.</p>
  
  <p><strong>Finally my question:</strong></p>
  
  <p>How do I get a spy instance of a Spring-Data Repository in my UnitTest with @Autowired?</p>