You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Spring中RabbitListenerEndpointRegistry编写更优JUnit测试

优化RabbitMQ队列启停Controller的JUnit测试方案

我来帮你优化这个RabbitMQ队列启停Controller的JUnit测试,原测试确实有不少可以简化和规范的地方,咱们一步步来调整:

原测试的主要问题

  • 用错了测试工具:MockRestServiceServer是用来测试RestTemplate调用外部服务的,而你的Controller是对外提供接口的,应该用MockMvc来模拟HTTP请求,更贴近真实调用场景。
  • 手动管理Controller实例:你自己new了QueueController,还手动set依赖,其实可以让Spring帮你管理,更符合Spring项目的测试规范。
  • 冗余的匿名类实现:手动写MessageListenerContainer的匿名实现太繁琐,直接用Mockito mock这个接口就好。
  • 上下文加载过重:原测试加载了不必要的Bean(比如ObjectMapper),其实测试Controller只需要加载Web层相关的组件就行。

优化后的测试代码

package com.compnay.depart.rest;

import static org.mockito.Mockito.verify;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(QueueController.class)
public class QueueControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;

    @MockBean
    private MessageListenerContainer messageListenerContainer;

    @Test
    void testStartEndpoint() throws Exception {
        // 模拟registry返回我们mock的容器实例
        org.mockito.Mockito.when(rabbitListenerEndpointRegistry.getListenerContainer(QueueController.LISTENER_ID))
                .thenReturn(messageListenerContainer);

        // 模拟GET请求,验证响应状态和内容
        mockMvc.perform(get("/" + QueueController.LISTENER_ID + "/start"))
                .andExpect(status().isOk())
                .andExpect(content().string("started"));

        // 关键验证:确保容器的start方法确实被Controller调用了
        verify(messageListenerContainer).start();
    }

    @Test
    void testStopEndpoint() throws Exception {
        org.mockito.Mockito.when(rabbitListenerEndpointRegistry.getListenerContainer(QueueController.LISTENER_ID))
                .thenReturn(messageListenerContainer);

        mockMvc.perform(get("/" + QueueController.LISTENER_ID + "/stop"))
                .andExpect(status().isOk())
                .andExpect(content().string("stopped"));

        // 验证stop方法被调用
        verify(messageListenerContainer).stop();
    }
}

优化点说明

  1. 使用@WebMvcTest注解:这个注解是Spring Boot专门为测试MVC控制器设计的,只会加载Web层相关的Bean(比如Controller、请求映射器等),测试启动更快,也避免了加载不必要的组件。
  2. 用MockMvc模拟HTTP请求:这是测试RestController的标准方式,能模拟真实的HTTP请求,同时可以验证响应状态码、响应内容,比直接调用Controller方法更贴近实际使用场景。
  3. Mockito自动注入依赖:用@MockBean注解自动创建并注入mock的RabbitListenerEndpointRegistry和MessageListenerContainer,不需要手动写setter,代码更简洁。
  4. 增加核心逻辑验证:原测试只验证了返回值,现在通过verify方法确保Controller确实调用了容器的start/stop方法,测试覆盖更全面。
  5. 升级到JUnit 5:改用JUnit 5的@Test注解(不需要加public修饰符),这是当前Java测试的主流框架,功能更丰富。

另外,原Controller里为测试写的getter/setter可以删掉了,因为@WebMvcTest配合@MockBean会自动完成依赖注入,不需要手动管理。

内容的提问来源于stack exchange,提问作者mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:22:53