Search code examples
javaamazon-web-servicesmockitotestngamazon-sqs

How to mock AmazonSQS in unit test to not make a call to SQS?


I have the following method in my Java class:

public class AwsHelper {

  private AmazonSQS sqs;

  private void sendMessageToQueue(String message){

        sqs = AmazonSQSClientBuilder.defaultClient();

        SendMessageRequest sendMessageRequest = new SendMessageRequest();
        sendMessageRequest.setQueueUrl("");
        sendMessageRequest.setMessageBody(message);
        sendMessageRequest.setMessageGroupId("");

        sqs.sendMessage(sendMessageRequest);
}

I want to be able to mock the behavior of sqs.sendMessage(sendMessageRequest);so that my unit test does not send a message to a queue.

I have tried to do so as follows in my test class, but sqs actually sends a message to the queue when my test is executed. Assume this is due to being assigned by AmazonSQSClientBuilder.defaultClient().

How can I solve this?

public class AwsSQSReferralsUtilTest {
    
        @Spy
        @InjectMocks
        private AwsHelper awsHelper;
    
        @Mock
        AmazonSQS sqs;
    
        @BeforeClass
        public void setUp() {
            MockitoAnnotations.initMocks(this);
        }
    
        @AfterMethod
        public void afterEachMethod() {
            Mockito.reset(awsHelper);
        }
    
        @Test
        public void shouldSendMessage() {
    
            Mockito.when((sqs.sendMessage(any(SendMessageRequest.class)))).thenReturn(new SendMessageResult());
    
            awsHelper.sendMessageToQueue("");
        }
}

Solution

  • I recommend to use approach from article: https://github.com/mockito/mockito/wiki/Mocking-Object-Creation

    You need to change little bit a class, applying approach for mocking from article in following way:

    AwsHelper

    public class AwsHelper {
    
        private AmazonSQS sqs;
    
        public void sendMessageToQueue(String message) {
            sqs = defaultClient();
    
            SendMessageRequest sendMessageRequest = new SendMessageRequest();
            sendMessageRequest.setQueueUrl("");
            sendMessageRequest.setMessageBody(message);
            sendMessageRequest.setMessageGroupId("");
    
            sqs.sendMessage(sendMessageRequest);
        }
    
        protected AmazonSQS defaultClient() {
            return AmazonSQSClientBuilder.defaultClient();
        }
    }
    
    

    AwsSQSReferralsUtilTest

    public class AwsSQSReferralsUtilTest {
    
        @Spy
        private AwsHelper awsHelper;
    
        @Mock
        private AmazonSQS sqs;
    
        @BeforeClass
        public void setUp() {
            MockitoAnnotations.initMocks(this);
        }
        
        @AfterMethod
        public void afterEachMethod() {
            Mockito.reset(awsHelper);
        }
    
        @Test
        public void shouldSendMessage() {
            //mocking object creation
            doReturn(sqs).when(awsHelper).defaultClient();
    
            when(sqs.sendMessage(any(SendMessageRequest.class))).thenReturn(new SendMessageRequest());
            awsHelper.sendMessageToQueue("");
        }
    
    }