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();
}
}
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);