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

如何在Spring控制器集成测试中Mock HandlerInterceptorAdapter?

如何在Spring集成测试中Mock HandlerInterceptorAdapter?

针对你现在的场景——用XML配置的FooInterceptor,并且集成测试用了@WebAppConfiguration和SpringJUnit4ClassRunner,我给你梳理两种实用的方案:

方法一:用@MockBean快速替换(推荐,适用于Spring 4.3+或Spring Boot)

如果你的Spring版本在4.3及以上,或者项目是Spring Boot的话,@MockBean绝对是最省事的办法。它会自动帮你把Spring上下文中的FooInterceptor实例替换成Mockito的Mock对象,完全不用改原有的XML配置。

直接在测试类里这么写就行:

@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "/context.xml")
@ActiveProfiles(...)
public class YourControllerIntegrationTest {

    // 用@MockBean标记,Spring会自动替换上下文中的真实实例
    @MockBean
    private FooInterceptor fooInterceptor;

    // 注入测试用的MockMvc,用来模拟请求
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testControllerWithMockedInterceptor() throws Exception {
        // 先指定拦截器的行为,比如让preHandle返回true,避免拦截请求
        when(fooInterceptor.preHandle(any(HttpServletRequest.class), 
                                      any(HttpServletResponse.class), 
                                      any(Object.class)))
            .thenReturn(true);

        // 模拟请求你的控制器接口
        mockMvc.perform(get("/your/controller/path"))
            .andExpect(status().isOk());

        // 还能验证拦截器的方法有没有被调用
        verify(fooInterceptor, times(1))
            .preHandle(any(HttpServletRequest.class), 
                       any(HttpServletResponse.class), 
                       any(Object.class));
    }
}

方法二:传统XML上下文覆盖(适用于旧版Spring)

如果你的Spring版本比较老,不支持@MockBean,那可以创建一个测试专用的XML配置,覆盖原有的拦截器定义:

  1. 新建一个test-context.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 覆盖原拦截器配置,用Mockito创建Mock实例 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean id="fooInterceptor" class="org.mockito.Mockito" factory-method="mock">
                <constructor-arg value="my.package.FooInterceptor"/>
            </bean>
        </mvc:interceptor>
    </mvc:interceptors>

    <!-- 导入原来的上下文,保证其他业务bean不受影响 -->
    <import resource="/context.xml"/>
</beans>
  1. 然后在测试类里指定这个测试上下文:
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "/test-context.xml")
@ActiveProfiles(...)
public class YourControllerIntegrationTest {

    // 这里注入的就是Mock的拦截器实例了
    @Autowired
    private FooInterceptor fooInterceptor;

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testControllerWithMockedInterceptor() throws Exception {
        // 设置Mock行为,和第一种方法一样
        when(fooInterceptor.preHandle(any(HttpServletRequest.class), 
                                      any(HttpServletResponse.class), 
                                      any(Object.class)))
            .thenReturn(true);

        // 执行测试请求
        mockMvc.perform(get("/your/controller/path"))
            .andExpect(status().isOk());

        // 验证拦截器方法调用
        verify(fooInterceptor).preHandle(any(), any(), any());
    }
}

注意:两种方法都需要确保你的测试依赖里包含mockito-core,不然没法创建Mock对象哦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:08:08