Тестирование JMS - отправка JMSTemplate не выполнена

У меня есть часть кода, отправляющая сообщения jms через Spring JMSTemplate. Для тестирования метода я использую Mockito.

Мой код выглядит следующим образом.... publishDialogueServiceMessage()->

 brokerUrl = jmsQueueProperties.getProperty(MessageRouterConstants.JMS_QUEUE_URL);  
        LOG.info("The broker url is : {}", brokerUrl);  
        jmsTemplate.send(jmsQueueProperties.getProperty(MessageRouterConstants.QUEUE), new MessageCreator() {

            @Override
            public Message createMessage(Session session) throws JMSException {             
                ObjectMessage obj = session.createObjectMessage(serviceResponse);
                messageSent = true;
                return obj;
            }
        });

В приведенном выше коде я установил логическую переменную true, чтобы проверить, отправлено ли сообщение

Мой тест выглядит следующим образом:

@Before
    public void setUp() throws Exception {

        connectionFactory = Mockito.spy(new ActiveMQConnectionFactory(
                "vm://localhost?broker.persistent=false"));
        conn = connectionFactory.createConnection();
        conn.start();       
    } 

@After
public void cleanUp() throws Exception{
    conn.stop();
}


@Test
    public void testPublishDialogueServiceMessage()
    {
        ServiceResponse response = Mockito.mock(
                ServiceResponse.class, Mockito.withSettings()
                        .serializable());
        JmsTemplate mockTemplate = Mockito.mock(JmsTemplate.class);
        java.util.Properties p = Mockito.mock(java.util.Properties.class);      
        Mockito.when(p.getProperty(MessageRouterConstants.QUEUE))
                .thenReturn("outbound.request.queue");
        mockTemplate.setConnectionFactory(connectionFactory);
        mockTemplate.setDeliveryPersistent(true);
        mockTemplate.setSessionAcknowledgeMode(2);
        mockTemplate.setSessionTransacted(true);

        ReflectionTestUtils.setField(publisher, "jmsQueueProperties", p);
        ReflectionTestUtils.setField(publisher, "jmsTemplate", mockTemplate);

        // test
        publisher.publishDialogueServiceMessage(response);
        ArgumentCaptor<MessageCreator> msgCreator = ArgumentCaptor.forClass(MessageCreator.class);
        Mockito.verify(p, Mockito.times(2))
                .getProperty(Mockito.anyString());
        Mockito.verify(mockTemplate, Mockito.times(1)).send(
                Mockito.anyString(), Mockito.any(MessageCreator.class));

        //MessageCreator msgCrt = Mockito.spy(msgCreator.getValue());
        //Assert.notNull(msgCrt);

        Assert.isTrue(publisher.isMessageSent());
    }

В тесте я столкнулся с интересной проблемой, так как publisher.isMessageSent() всегда возвращает мне ЛОЖЬ, указывая, что сообщение отправки не выполнено (?). но Mockito.verify(mockTemplate, Mockito.times(1)).send(Mockito.anyString(), Mockito.any(MessageCreator.class)); работает нормально.

Мне интересно, в чем причина того, что моя переменная messageSent не установлена. Может ли кто-нибудь пролить свет, что я могу делать неправильно.


person kuhajeyan    schedule 10.05.2013    source источник


Ответы (1)


Просто у вас есть макет для jmsTemplate (ваш mockTemplate). Когда метод вызывается для макета, он не делает ничего, кроме записи вызова макета. Таким образом, макет не знает, что он должен попытаться вызвать функцию msgCreator.

Глядя на ваш тест, я вижу некоторые очевидные проблемы, которые предполагают отсутствие знаний о Mockito. Почему вы устанавливаете все эти поля на mockTemplate? Это макет, он все равно не будет использовать эти поля. Это также говорит о том, что вам не нужен код в ваших @Before и @After.

Если вы ДЕЙСТВИТЕЛЬНО хотите, чтобы ваш тест отправлял сообщение через JMS (и тем самым вызывал средство создания сообщений), вы должны использовать spy на JmsTemplate вместо макета. Однако я бы крайне не одобрял этого, так как ваш тест будет зависеть от внешней системы, и вы, по сути, будете тестировать JsmTemplate. Достаточно того факта, что ваш макет вызывается правильно. Единственная дополнительная вещь, которую, я думаю, вам нужно сделать, это вызвать создателя сообщения, передаваемого макету, чтобы убедиться, что он правильно создает сообщение.

person John B    schedule 10.05.2013
comment
@JonhB Спасибо, Джон. Это помогает мне. - person kuhajeyan; 12.05.2013