My service method looks like below, I am trying to mock JmsTemplate so that it can send message during unit testing, but it doesn't execute jmsTemplate.send(...), it directly goes to next line, How can i execute jmsTemplate.send(..) part of code of my service class using unit testing?
public int invokeCallbackListener(final MyObject payload, final MyTask task) throws Exception{
//create map of payload and taskId
int taskStatusCd = task.getTaskSatus().getCode();
final Map<String, Object> map = new HashMap<String, Object>();
map.put(PAYLOAD_KEY, payload);
map.put(TASK_ID_KEY, task.getTaskId());
//generate JMSCorrelationID
final String correlationId = UUID.randomUUID().toString();
String requestQueue = System.getProperty("REQUEST_QUEUE");
requestQueue = requestQueue!=null?requestQueue:ExportConstants.DEFAULT_REQUEST_QUEUE;
jmsTemplate.send(requestQueue, new MessageCreator() {
@Override
public Message createMessage(Session session) throws JMSException {
***ObjectMessage message = session.createObjectMessage((Serializable)map)***; //fail here. Message returns null
message.setJMSCorrelationID(correlationId);
message.setStringProperty(MESSAGE_TYPE_PROPERTY,payload.getMessageType().getMessageType());
return message;
}
});
l.info("Request Message sent with correlationID: " + correlationId);
taskStatusCd = waitForResponseStatus(task.TaskId(), taskStatusCd, correlationId);
return taskStatusCd;
}
This is my test class code.
RemoteInvocationService remoteInvocationService;
JmsTemplate mockTemplate;
Session mockSession;
Queue mockQueue;
ObjectMessage mockMessage;
MessageCreator mockmessageCreator;
@Before
public void setUp() throws Exception {
remoteInvocationService = new RemoteInvocationService();
mockTemplate = mock(JmsTemplate.class);
mockSession = mock(Session.class);
mockQueue = mock(Queue.class);
mockMessage = mock(ObjectMessage.class);
mockmessageCreator = mock(MessageCreator.class);
when(mockSession.createObjectMessage()).thenReturn(mockMessage);
when(mockQueue.toString()).thenReturn("testQueue");
Mockito.doAnswer(new Answer<Message>() {
@Override
public Message answer(final InvocationOnMock invocation) throws JMSException {
final Object[] args = invocation.getArguments();
final String arg2 = (String)args[0];
final MessageCreator arg = (MessageCreator)args[1];
return arg.createMessage(mockSession);
}
}).when(mockTemplate).send(Mockito.any(MessageCreator.class));
mockTemplate.setDefaultDestination(mockQueue);
remoteInvocationService.setJmsTemplate(mockTemplate);
}
@Test
public void testMessage() throws Exception{
MyTask task = new MyTask();
task.setTaskSatus(Status.Pending);
remoteInvocationService.invokeCallbackListener(new MyObject(), task);
}
I have below code which receives message but, I am getting status object null.
Message receivedMsg = jmsTemplate.receiveSelected(responseQueue, messageSelector);if(receivedMsg instanceof TextMessage){
TextMessage status = (TextMessage) receivedMsg;
l.info(status.getText());}
below test code:
TextMessage mockTextMessage;
when(mockSession.createTextMessage()).thenReturn(mockTextMessage);
mockTextMessage.setText("5");
when(mockTemplate.receiveSelected(Mockito.any(String.class), Mockito.any(String.class))).thenReturn(mockTextMessage)
You are mocking the send
method that accepts only one parameter (MessageCreator
), but you are actually calling the one that accepts two (String, MessageCreator
).
Add the String
to your mock:
Mockito.doAnswer(new Answer<Message>() {
@Override
public Message answer(final InvocationOnMock invocation) throws JMSException {
final Object[] args = invocation.getArguments();
final MessageCreator arg = (MessageCreator)args[0];
return arg.createMessage(mockSession);
}
}).when(mockTemplate).send(Mockito.any(String.class), Mockito.any(MessageCreator.class));
There is another mistake when mocking the sesssion. You are mocking the method without parameterers:
when(mockSession.createObjectMessage()).thenReturn(mockMessage);
but you actually need to mock the one with the Serializable param:
when(mockSession.createObjectMessage(Mockito.any(Serializable.class)).thenReturn(mockMessage);