title: How to mock out AWS properly for this unit test?
body: <p>I want to write a Spring app that listens for SQS messages and then downloads a file from S3.  I have all that working, but I am running into problems writing unit tests for areas of the code that aren't involved in AWS.  I want to mock out all the AWS for the test, but I keep getting this error and I haven't found a way to fix it yet</p>
  
  <p>Thank you for any clues</p>
  
  <pre><code>Error creating bean with name 'simpleMessageListenerContainer' 
  defined in class path resource org/springframework/cloud/aws/messaging/config/annotation/SqsConfiguration.class
  Invocation of init method failed; nested exception is java.lang.NullPointerException
  </code></pre>
  
  <p>Here is my simplified demo project that demonstrates the problem.</p>
  
  <p>Test class</p>
  
  <pre><code>package com.example.demo;
  
  import lombok.extern.slf4j.Slf4j;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.boot.test.mock.mockito.MockBean;
  import org.springframework.test.context.TestPropertySource;
  import org.springframework.test.context.junit4.SpringRunner;
  import static org.junit.Assert.assertEquals;
  
  @Slf4j
  @RunWith(SpringRunner.class)
  @SpringBootTest(classes = TestConfig.class)
  @TestPropertySource(locations= "classpath:application.yml")
  public class DemoApplicationTests {
  
    @MockBean
    DemoApplication demoApplication;
  
    @Test
    public void nonAwsRelatedTest() {
      int foo = 1;
      assertEquals(1, foo);
    }
  }
  </code></pre>
  
  <p>TestConfig class</p>
  
  <pre><code>package com.example.demo;
  
  import com.amazonaws.services.sqs.AmazonSQSAsync;
  import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
  import org.springframework.boot.test.context.TestConfiguration;
  import org.springframework.boot.test.mock.mockito.MockBean;
  import org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration;
  import org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration;
  import org.springframework.cloud.aws.messaging.config.SimpleMessageListenerContainerFactory;
  import org.springframework.cloud.aws.messaging.listener.QueueMessageHandler;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Primary;
  import static org.mockito.Mockito.mock;
  
  @TestConfiguration
  @EnableAutoConfiguration(exclude = {MessagingAutoConfiguration.class, ContextStackAutoConfiguration.class})
  public class TestConfig {
  
    @MockBean
    AWSConfiguration awsConfiguration;
    @MockBean
    AWS aws;
    @MockBean
    AmazonSQSAsync amazonSQSAsync;
  
    @Bean
    @Primary
    public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory() {
      SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
      factory.setAutoStartup(false);
      return factory;
    }
  
    @Bean(name = "messageHandler")
    public QueueMessageHandler messageHandler() {
      return mock(QueueMessageHandler.class);
    }
  
    @Bean(name = "amazonSQSAsync")
    public AmazonSQSAsync amazonSQSAsync() {
      return mock(AmazonSQSAsync.class);
    }
  }
  </code></pre>
  
  <p>Application class</p>
  
  <pre><code>package com.example.demo;
  
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.boot.CommandLineRunner;
  import org.springframework.boot.SpringApplication;
  import org.springframework.boot.autoconfigure.SpringBootApplication;
  
  @Slf4j
  @SpringBootApplication
  public class DemoApplication implements CommandLineRunner {
  
    public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
    }
  
    @Override
    public void run(String... args) throws Exception {
      while(true) {
        Thread.sleep(1000);
      }
    }
  }
  </code></pre>
  
  <p>AWS class</p>
  
  <pre><code>package com.example.demo;
  
  import com.amazonaws.services.s3.AmazonS3;
  import com.amazonaws.services.s3.model.PutObjectResult;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener;
  import org.springframework.stereotype.Component;
  import java.io.File;
  
  @Slf4j
  @Component
  public class AWS {
  
    @Autowired
    private AmazonS3 amazonS3;
  
    @Value("${aws.s3.bucket}")
    private String bucket;
  
    PutObjectResult upload(String filePath, String uploadKey) {
      File file = new File(filePath);
      return amazonS3.putObject(bucket, uploadKey, file);
    }
  
    @SqsListener("mysqsqueue")
    public void queueListener(String message) {
      System.out.println("Got an SQS message: " + message);
    }
  }
  </code></pre>
  
  <p>AWS configuration class</p>
  
  <pre><code>package com.example.demo;
  
  import com.amazonaws.auth.AWSCredentials;
  import com.amazonaws.auth.AWSCredentialsProvider;
  import com.amazonaws.services.s3.AmazonS3;
  import com.amazonaws.services.s3.AmazonS3ClientBuilder;
  import com.amazonaws.services.sqs.AmazonSQSAsync;
  import com.amazonaws.services.sqs.AmazonSQSAsyncClientBuilder;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.cloud.aws.messaging.config.annotation.EnableSqs;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.context.annotation.Primary;
  
  @Configuration
  @EnableSqs
  public class AWSConfiguration {
  
    @Value("${aws.region}")
    private String awsRegion;
  
    @Value("${aws.access-key}")
    private String awsAccessKey;
  
    @Value("${aws.secret-key}")
    private String awsSecretKey;
  
    @Bean
    @Primary
    public AmazonSQSAsync amazonSQSAsyncClient() {
      AmazonSQSAsync amazonSQSAsyncClient = AmazonSQSAsyncClientBuilder.standard()
          .withCredentials(amazonAWSCredentials())
          .withRegion(awsRegion)
          .build();
      return amazonSQSAsyncClient;
    }
  
    @Bean
    public AmazonS3 amazonS3Client() {
      AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
          .withCredentials(amazonAWSCredentials())
          .withRegion(awsRegion).build();
      return s3Client;
    }
  
    @Bean
    @Primary
    public AWSCredentialsProvider amazonAWSCredentials() {
      return new AWSCredentialsProvider() {
        public void refresh() {}
        public AWSCredentials getCredentials() {
          return new AWSCredentials() {
            public String getAWSSecretKey() {
              return awsSecretKey;
            }
            public String getAWSAccessKeyId() {
              return awsAccessKey;
            }
          };
        }
      };
    }
  }
  </code></pre>
  
  <p>application.yml</p>
  
  <pre><code>cloud:
    aws:
      stack:
        auto: false
  
  aws:
    enabled: false
    region: us-east-1
    user: foo
    access-key: ABCDE
    secret-key: 12345
  
    sqs:
      queue: mysqsqueue
  
    s3:
      bucket: mybucket
  
  spring:
    autoconfigure:
      exclude:
        - org.springframework.cloud.aws.autoconfigure.context.ContextInstanceDataAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.context.ContextCredentialsAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.context.ContextRegionProviderAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.context.ContextResourceLoaderAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.context.ContextStackAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.mail.MailSenderAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.cache.ElastiCacheAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.messaging.MessagingAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.jdbc.AmazonRdsDatabaseAutoConfiguration
        - org.springframework.cloud.aws.autoconfigure.metrics.CloudWatchExportAutoConfiguration
  </code></pre>
  
  <p>pom dependencies</p>
  
  <pre><code>    &lt;dependency&gt;
          &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
          &lt;artifactId&gt;lombok&lt;/artifactId&gt;
          &lt;optional&gt;true&lt;/optional&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-configuration-processor&lt;/artifactId&gt;
          &lt;version&gt;2.1.6.RELEASE&lt;/version&gt;
          &lt;optional&gt;true&lt;/optional&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter&lt;/artifactId&gt;
          &lt;version&gt;2.1.6.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
          &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
          &lt;version&gt;2.1.6.RELEASE&lt;/version&gt;
          &lt;scope&gt;test&lt;/scope&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
          &lt;artifactId&gt;spring-cloud-starter-aws&lt;/artifactId&gt;
          &lt;version&gt;2.1.2.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
          &lt;artifactId&gt;spring-cloud-aws-messaging&lt;/artifactId&gt;
          &lt;version&gt;2.1.2.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.integration&lt;/groupId&gt;
          &lt;artifactId&gt;spring-integration-aws&lt;/artifactId&gt;
          &lt;version&gt;2.2.0.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  </code></pre>