Search code examples
mockitosolace

Testing a Solace Producer With Mockito Returning a Null Connection


I'm trying to test the following @Service using Mockito that sends a message to a Solace queue. I can inject my @Mock for the SolConnectionFactory and call createQueueConnection() on the Mock but the Mock connection returned is set to null? I tried removing the QueueConnection connection = null; statement from the start of the Service but it didn't make a difference. Here's the Solace Service:

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;

@Service
public class SolaceProducerImpl implements SolaceProducer {

    @Autowired
    private SolConnectionFactory solaceCachedConnectionFactory; 

    @Override
    public SolaceResponse sendMessage(Queue queue, String message) throws JMSException {

        log.info("Starting - solaceProducerImpl.sendMessageToSolace()");

        QueueConnection connection = null;
        QueueSession session = null;
        QueueSender sender = null;
        SolaceResponse solaceResponse = new SolaceResponse();

        try {
            connection = solaceCachedConnectionFactory.createQueueConnection();         
            session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);                   
            sender = session.createSender(queue);           
            TextMessage textMessage = session.createTextMessage();
            textMessage.setText(message);               
            sender.send(textMessage);
        } catch (Exception ex) {
            //logged exception
        } finally {
            if (sender != null) {
                sender.close();
            }
            if (session != null) {
                session.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
        log.info("Finished - solaceProducerImpl.sendMessageToSolace()");
        return solaceResponse;
    }
}

And the test:

  import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.util.Assert;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.solacesystems.jms.SolConnectionFactory;


    @RunWith(MockitoJUnitRunner.class)
    public class SolaceProducerTest {   

        @Mock
        private SolConnectionFactory solaceCachedConnectionFactory; 

        @Mock
        private Queue queue;

        @Mock
        private QueueConnection connection; 

        @Mock
        private QueueSession queueSession;

        @Mock
        private QueueSender queueSender;

        @Mock
        private TextMessage textMessage;

        private static final String SAMPLE_TEXT = "Some Test Message";

        @InjectMocks
        private SolaceProducerImpl solaceProducer;

        @Test
        public void testSendMessage() throws JMSException { 
            Mockito.when(solaceCachedConnectionFactory.createConnection()).thenReturn(connection);
            Mockito.when(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)).thenReturn(queueSession);
            Mockito.when(queueSession.createSender(queue)).thenReturn(queueSender);         
            textMessage.setText(SAMPLE_TEXT);
            Mockito.when(queueSession.createTextMessage()).thenReturn(textMessage);
            SolaceResponse result = solaceProducer.sendMessage(queue, SAMPLE_TEXT);
            Assert.notNull(result);
            Mockito.verify(solaceCachedConnectionFactory, Mockito.times(1)).createConnection();
            Mockito.verify(connection, Mockito.times(1)).createSession(false, Session.AUTO_ACKNOWLEDGE);
            Mockito.verify(connection, Mockito.times(1)).close();
            Mockito.verify(queueSession, Mockito.times(1)).createSender(queue);
            Mockito.verify(queueSession, Mockito.times(1)).close();
            Mockito.verify(queueSender, Mockito.times(1)).send(textMessage);
            Mockito.verify(queueSender, Mockito.times(1)).close();
        }

    }

Solution

  • The issue appears to be Mockito not mocking solaceCachedConnectionFactory.createConnection(), resulting in it returning null despite instructions to do so.

    Mockito.when(solaceCachedConnectionFactory.createConnection()).thenReturn(connection);
    

    I did a quick test, and managed to solve the issue by instantiating the class under test.

    @InjectMocks
    private SolaceProducerImpl solaceProducer = new SolaceProducerImpl();
    

    Note that there are several other issues with the provided sample. For example, the sample has mistakenly mocked connection.createSession instead of connection.createQueueSession.

    session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);                   
    
    Mockito.when(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)).thenReturn(queueSession);