JMS测试 - JMSTemplate发送未执行

kuh*_*yan 0 junit unit-testing jms mockito spring-jms

我有代码片段通过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;
            }
        });
Run Code Online (Sandbox Code Playgroud)

在上面的代码我设置布尔变量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();
}
Run Code Online (Sandbox Code Playgroud)


@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());
    }
Run Code Online (Sandbox Code Playgroud)

在测试中我遇到一个有趣的问题,因为publisher.isMessageSent()总是返回FALSE,表示发送消息似乎没有执行(?).但是Mockito.verify(mockTemplate,Mockito.times(1)).send(Mockito.anyString(),Mockito.any(MessageCreator.class)); 很好.

我想知道我的messageSent变量没有设置的原因是什么.任何人都可以解释一下我可能做错了什么.

Joh*_*n B 7

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

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

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