为何使用Mockito测试IbmMqService时JmsTemplate.receive返回null对象
问题根因
你使用@Mock修饰的JmsTemplate是Mockito生成的纯模拟对象,本身没有任何真实业务逻辑实现:
- 调用
send方法不会真的存储消息,仅执行空逻辑无任何副作用 - 未做模拟配置的前提下,调用
receive这类非void方法默认返回null,就是你遇到的现象
解决方案
方案1:单元测试场景,保持用Mock JmsTemplate
如果你仅需要单元测试IbmMqService的业务逻辑,不需要真实收发消息,按以下步骤修改:
- 首先给测试类添加Mockito启动注解,确保
@Mock、@InjectMocks注解生效,JUnit5用@ExtendWith(MockitoExtension.class),JUnit4用@RunWith(MockitoJUnitRunner.class) - 测试类中
@Value字段默认不会自动注入,可通过@TestPropertySource注入测试配置值,或手动赋值 - 主动模拟
receive方法的返回值,不需要调用send方法模拟发消息
修改后的代码示例:
// JUnit5 示例代码 @ExtendWith(MockitoExtension.class) @TestPropertySource(properties = {"ibm.mq.queue.response=TEST_RESPONSE_QUEUE"}) public class ImqMqServerTest { @InjectMocks IbmMqService ibmMqService; @Mock JmsTemplate jmsTemplate; @Value("${ibm.mq.queue.response}") String responseMq; @Test void receiveOrderResponseTest() throws JMSException { // 构造模拟返回的消息对象 BytesMessage mockMessage = Mockito.mock(BytesMessage.class); // 模拟消息的属性/内容,按需添加 when(mockMessage.getJMSMessageID()).thenReturn("TEST_MESSAGE_12345"); // 配置JmsTemplate receive方法的模拟返回 when(jmsTemplate.receive(responseMq)).thenReturn(mockMessage); // 调用要测试的业务逻辑 Message message = jmsTemplate.receive(responseMq); System.out.println(message.getJMSMessageID()); // 输出TEST_MESSAGE_12345 } }
方案2:集成测试场景,需要真实收发消息
如果需要验证完整的消息收发流程,不要用Mock的JmsTemplate,改为注入真实的JmsTemplate实例,配合嵌入式MQ或者测试环境的MQ实例做集成测试即可。
内容的提问来源于stack exchange,提问作者Thivya Thogesan
相关产品推荐
相关产品推荐

