首页 > 解决方案 > 无法在 springboot 中为 JMSListner @MockBean

问题描述

我需要使用 mockito 测试 JMS 侦听器方法。

在测试类中,当我添加 @MockBean 以验证对模拟 bean 的某些方法调用时,测试失败。

package com.practice.ActiveMqPractice.listner;

import com.practice.ActiveMqPractice.utility.StringUtility;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
@EnableJms
public class MyListner {
@Autowired
private JmsTemplate jmsTemplate;

@Autowired private StringUtility stringUtility;

@JmsListener(destination = "foo")
public void handle(String in) {
    this.jmsTemplate.convertAndSend("bar", stringUtility.capitalize(in));
}
}

相应的测试类:这个测试类是“PASS”,但是当我取消注释这些行时:@MockBean private StringUtility stringUtility; 和验证(stringUtility,times(1)).capitalize(message); 下面,我得到了错误。错误进一步如下:

package com.practice.ActiveMqPractice.listner;

import com.practice.ActiveMqPractice.utility.StringUtility;
import com.practice.ActiveMqPractice.utility.Utility2;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.junit.jupiter.api.Assertions.*;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class MyListnerTest {

@Autowired
private JmsTemplate jmsTemplate;

/*@MockBean
private StringUtility stringUtility;*/

@Test
public void test() {
    String message = "Hello World";
    this.jmsTemplate.convertAndSend("foo", message);
    this.jmsTemplate.setReceiveTimeout(10_000);
    String s = jmsTemplate.receiveAndConvert("bar").toString();
    assertEquals(s, "HELLO WORLD");
    //verify(stringUtility, times(1)).capitalize(message);
}
}

例外情况如下:

org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.practice.ActiveMqPractice.listner.MyListner.handle(java.lang.String)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Cannot convert object of type [null] to JMS message. Supported message payloads are: String, byte array, Map<String,?>, Serializable object.
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:122) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:77) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1237) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1227) [spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1120) [spring-jms-5.3.6.jar:5.3.6]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_281]
Caused by: org.springframework.jms.support.converter.MessageConversionException: Cannot convert object of type [null] to JMS message. Supported message payloads are: String, byte array, Map<String,?>, Serializable object.
at org.springframework.jms.support.converter.SimpleMessageConverter.toMessage(SimpleMessageConverter.java:79) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.lambda$convertAndSend$5(JmsTemplate.java:661) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:604) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.lambda$send$3(JmsTemplate.java:586) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584) ~[spring-jms-5.3.6.jar:5.3.6]
at org.springframework.jms.core.JmsTemplate.convertAndSend(JmsTemplate.java:661) ~[spring-jms-5.3.6.jar:5.3.6]
at com.practice.ActiveMqPractice.listner.MyListner.handle(MyListner.java:20) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_281]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_281]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_281]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_281]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) ~[spring-messaging-5.3.6.jar:5.3.6]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) ~[spring-messaging-5.3.6.jar:5.3.6]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114) ~[spring-jms-5.3.6.jar:5.3.6]
... 10 common frames omitted

标签: spring-bootmockitojunit4spring-jmsspring-boot-test

解决方案


您需要告诉 Mockito 在调用 capitalize 时要做什么,默认情况下,模拟将返回null,这就是您看到该错误的原因。


推荐阅读