title: Spring Test Service Autowiring resulting in null
body: <p>I am able to run a Rest Controller PUT method that uses a Autowired @Service as expected via the Spring Boot Application. The same Autowiring is failing while trying to perform a Spring JUnit Test. I have tried reading through multiple threads with similar issues. I made sure I am NOT creating the @Service through the "new" keyword and I tried Context Configuration and other methods .. but all seems to be in vain. I am not sure where I am going wrong. </p>
  
  <p>My Spring Boot Application class - </p>
  
  <pre><code>@SpringBootApplication    
  @ComponentScan({    
          "com.initech.myapp.*"    
          })    
  public class IngestionServerApplication {    
  
      private static final Log logger = LogFactory.getLog(IngestionServerApplication.class);    
  
      public static void main(String[] args) {    
          SpringApplication.run(IngestionServerApplication.class, args);    
          logger.info("Ingestion Server Application started...");    
      }    
  }
  </code></pre>
  
  <p>Rest Controller Class - </p>
  
  <pre><code>package com.initech.myapp.ingestion.controller;  
  
  @RestController  
  public class IngestionController extends BaseRestController {  
  
      private static final Log logger = LogFactory.getLog(IngestionController.class);  
  
      // This variable is getting "null" autowiring if invoked 
      // via Spring Unit Testing framework while it is injected fine via
      // Spring Boot app invocation.
      @Autowired  
      public IngestionPayloadProcessor payloadProcessor;
  
      @RequestMapping(path = "/ingest", method = RequestMethod.PUT,  
              consumes = {  
                      MediaType.APPLICATION_JSON_VALUE,  
                      MediaType.APPLICATION_XML_VALUE  
              },  
              produces = {  
                      MediaType.APPLICATION_JSON_VALUE  
              })  
      public IngestionSuccessResponse ingest(@RequestHeader(value = "authToken", required = true) String authToken,                          
                           @RequestBody String jsonBody) throws Exception  {  
  
          IngestionPayload ingestionPayload = new IngestionPayload();  
          ingestionPayload.setAuthToken(authToken);  
          ingestionPayload.setJsonBody(jsonBody);  
  
          IngestionSuccessResponse ingestionSuccessResponse = payloadProcessor.process(ingestionPayload);  
  
          return ingestionSuccessResponse;  
      }  
  }
  </code></pre>
  
  <p>Service Class</p>
  
  <pre><code>package com.initech.myapp.ingestion.app.service;
  
  @Service
  @ImportResource({"spring.xml"})
  public class IngestionPayloadProcessor {
  
      private static final Log logger = LogFactory.getLog(IngestionPayloadProcessor.class);
  
      @Resource(name = "kafkaConfig")
          private Properties kafkaConfig;
  
      @Value("${kakfaTopic}")
          private String kakfaTopic;
  
      public IngestionSuccessResponse process(IngestionPayload ingestionPayload) throws Exception {
              try {
  
              IngestionSuccessResponse ingestionSuccessResponse = buildSuccessResponse(ingestionPayload);
  
              return ingestionSuccessResponse;
                      }
                  catch (IllegalStateException e)
                  {
                      logger.error("Encountered exception while dropping message in Kafka... " + e.getMessage());
                          throw e;
                      }
              }
              }
  
  private buildSuccessResponse() { ... }
  </code></pre>
  
  <p>Spring Unit Testing</p>
  
  <pre><code>@RunWith(SpringRunner.class)
  @ContextConfiguration(locations = "classpath*:/spring.xml")
  @WebMvcTest(IngestionServerApplication.class)
  public class IngestionServerApplicationTests {
      @Autowired
      private MockMvc mockMvc;
  
      @Before
      public void setUp() throws Exception {
          mockMvc = MockMvcBuilders.standaloneSetup(
                      new IngestionServiceController())
                              .build();
                  }
  
      @Test
      public void testIngestService() throws Exception {
  
          HttpHeaders httpHeaders = new HttpHeaders();
                  httpHeaders.add("authToken","safdafio12312asdfs23");
                  RequestBuilder requestBuilder = put("/ingest").content("{'testKey' : 'testVal'}").accept(MediaType.APPLICATION_JSON).headers(httpHeaders);
  
          this.mockMvc.perform(requestBuilder).andExpect(status().isOk());
      }
  }
  </code></pre>
  
  <p>Error Logs</p>
  
  <pre><code>2016-08-10 19:24:36.500 DEBUG 7505 --- [           main] m.m.a.RequestResponseBodyMethodProcessor : Read [class java.lang.String] as "application/json" with [org.springframework.http.converter.StringHttpMessageConverter@49aa766b]
  2016-08-10 19:24:36.510 DEBUG 7505 --- [           main] .m.m.a.ExceptionHandlerExceptionResolver : Resolving exception from handler [public com.initech.myapp.ingestion.model.IngestionSuccessResponse com.initech.myapp.ingestion.app.controller.myappIngestionServiceController.ingest(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.lang.Exception]: java.lang.NullPointerException
  2016-08-10 19:24:36.512 DEBUG 7505 --- [           main] .m.m.a.ExceptionHandlerExceptionResolver : Invoking @ExceptionHandler method: public org.springframework.http.ResponseEntity&lt;java.util.Map&lt;java.lang.String, java.lang.Object&gt;&gt; com.initech.myapp.base.controller.BaseRestController.handleException(java.lang.Exception,javax.servlet.http.HttpServletRequest)
  This is the error handler...
  2016-08-10 19:24:36.514  INFO 7505 --- [           main] p.d.i.a.c.myappIngestionServiceController : &gt; handleNoResultException
  2016-08-10 19:24:36.574 DEBUG 7505 --- [           main] o.s.w.s.m.m.a.HttpEntityMethodProcessor  : Written [{status=500, authToken=6acb1a5c-2ced-4690-95b3-eb7957c7c28a, error=null}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@50d3bf39]
  
  java.lang.AssertionError: Status 
  Expected :200
  Actual   :500
  </code></pre>
  
  <p>Note that I have debugged through the test and I can see that the NullPointer exception is thrown at the below line in the Rest Controller Class as the payloadProcessor object is null.</p>
  
  <pre><code>IngestionSuccessResponse ingestionSuccessResponse = payloadProcessor.process(ingestionPayload);
  </code></pre>
  
  <p>=====</p>
  
  <h1><strong>Unit Test with Mock objects: (This is working as expected)</strong></h1>
  
  <pre><code>@RunWith(SpringRunner.class)
  @ActiveProfiles("dev")
  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  @AutoConfigureMockMvc
  public class IngestionServerUnitTests {
  
      @Autowired
      private MockMvc mockMvc;
  
      @MockBean
      private IngestionPayloadProcessor processor;
  
      // I was able to get this to work by removing the setUp() method 
      // that was originally in my code. It was trying to build a new instance
      // of the REST controller and then run the "perform" on top of it
      // which was causing the test to fail I assume!
  
      /*@Before
      public void setUp() throws Exception {
          mockMvc = MockMvcBuilders.standaloneSetup(
                  new IngestionServiceController())
                  .build();
      }*/
  
      @Test
      public void testIngestService() throws Exception {
  
          IngestionSuccessResponse ingestionSuccessResponse = new IngestionSuccessResponse();
          ingestionSuccessResponse.setStatusCode("200");
          ingestionSuccessResponse.setRequestId("6acb1a5c-2ced-4690-95b3-eb7957c7c28a");
          ingestionSuccessResponse.setReceivedTimestamp("2016-08-09T19:43:30.02234312");
  
          given(this.processor.process(anyObject())).willReturn(ingestionSuccessResponse);
  
          HttpHeaders httpHeaders = new HttpHeaders();
          httpHeaders.add("Authorization","5e18685c95b34690");
  
          RequestBuilder requestBuilder = put("/ingest").content("&lt;test&gt;test data&lt;/test&gt;").accept(MediaType.APPLICATION_JSON).headers(httpHeaders);
  
          this.mockMvc.perform(requestBuilder).andExpect(status().isOk());
      }
  
  }
  </code></pre>