0

我有代码片段通过 Spring JMSTemplate 发送 jms 消息。为了测试我使用 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()总是返回 FALSE,表明发送消息似乎没有执行(?)。但是Mockito.verify(mockTemplate, Mockito.times(1)).send(Mockito.anyString(), Mockito.any(MessageCreator.class)); 一切顺利。

我想知道我的 messageSent 变量未设置的原因是什么。谁能阐明我可能做错了什么。

4

1 回答 1

7

很简单,你有一个jmsTemplate(你的mockTemplate)的模拟。当在模拟上调用方法时,除了记录对模拟的调用外,它不会做任何事情。所以模拟不知道它应该尝试调用msgCreator.

查看您的测试,我发现一些明显的问题表明缺乏对 Mockito 的了解。你为什么要设置所有这些字段mockTemplate?这是一个模拟,无论如何它都不会使用这些字段。这也表明您不需要@Beforeand中的代码@After

如果您真的希望您的测试通过 JMS 发送消息(从而调用消息创建器),您应该使用spyonJmsTemplate而不是 mock。但是,我强烈反对这种做法,因为您的测试将依赖于外部系统,而您实际上是在进行测试JsmTemplate。您的模拟被正确调用的事实就足够了。我认为您需要做的唯一额外的事情是调用传递给模拟的消息创建者以验证它是否正确创建了消息。

于 2013-05-10T10:42:36.073 回答