title: Why component scanning does not work for Spring Boot unit tests?
body: <p>The service class <code>FooServiceImpl</code> is annotated with <a href="https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/Service.html" rel="nofollow noreferrer">@Service</a> aka <code>@Component</code> which makes it eligible for autowiring. Why this class is not being picked up and autowired during unit tests?</p>
  
  <pre><code>@Service
  public class FooServiceImpl implements FooService {
      @Override
      public String reverse(String bar) {
          return new StringBuilder(bar).reverse().toString();
      }
  }
  
  @RunWith(SpringRunner.class)
  //@SpringBootTest
  public class FooServiceTest {
      @Autowired
      private FooService fooService;
      @Test
      public void reverseStringShouldReverseAnyString() {
          String reverse = fooService.reverse("hello");
          assertThat(reverse).isEqualTo("olleh");
      }
  }
  </code></pre>
  
  <p>The test failed to load application context,</p>
  
  <pre><code>2018-02-08T10:58:42,385 INFO    Neither @ContextConfiguration nor @ContextHierarchy found for test class [io.github.thenilesh.service.impl.FooServiceTest], using DelegatingSmartContextLoader
  2018-02-08T10:58:42,393 INFO    Could not detect default resource locations for test class [io.github.thenilesh.service.impl.FooServiceTest]: no resource found for suffixes {-context.xml}.
  2018-02-08T10:58:42,394 INFO    Could not detect default configuration classes for test class [io.github.thenilesh.service.impl.FooServiceTest]: FooServiceTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
  2018-02-08T10:58:42,432 INFO    Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, (...)org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
  2018-02-08T10:58:42,448 INFO    Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@f0ea28, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@16efaab,(...)org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@9604d9]
  2018-02-08T10:58:42,521 INFO    Refreshing org.springframework.context.support.GenericApplicationContext@173f9fc: startup date [Thu Feb 08 10:58:42 IST 2018]; root of context hierarchy
  2018-02-08T10:58:42,606 INFO    JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
  2018-02-08T10:58:42,666 ERROR    Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@19aaa5] to prepare test instance [io.github.thenilesh.service.impl.FooServiceTest@57f43]
  org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'io.github.thenilesh.service.impl.FooServiceTest': Unsatisfied dependency expressed through field 'fooService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.github.thenilesh.service.FooService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
      at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      . . . 
      at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) [.cp/:?]
  Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.github.thenilesh.service.FooService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
      ... 28 more
  2018-02-08T10:58:42,698 INFO    Closing org.springframework.context.support.GenericApplicationContext@173f9fc: startup date [Thu Feb 08 10:58:42 IST 2018]; root of context hierarchy
  </code></pre>
  
  <p><a href="https://gist.github.com/TheNilesh/3bb6cf7bef40d1706d9d939118f66886" rel="nofollow noreferrer">Full stack trace</a></p>
  
  <p>If test class is annotated with <a href="https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/SpringBootTest.html" rel="nofollow noreferrer">@SpringBootTest</a> then it creates whole application context including database connection and a lot of unrelated beans which obviously not needed for this unit test(It won't be <em>unit</em> test then!). What is expected is that only beans on which <code>FooService</code> depends should be instantiated, except which are mocked, with <code>@MockBean</code>.</p>