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

如何Mock Aspect切面类的方法,避免Controller测试触发不必要的数据库调用

解决方案

你可以根据测试场景选择以下任意一种方案实现需求:

方案1:直接Mock整个切面类(最推荐,适配Controller切片测试场景)

如果你的测试是@WebMvcTest切片测试或者@SpringBootTest集成测试,直接用Spring Boot提供的@MockBean注解替换容器中的真实切面实例,自定义切面方法的逻辑完全跳过原有数据库操作即可:

import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@WebMvcTest(SampleController.class)
class SampleControllerTest {
    // 将容器中的SampleAspect替换为Mock对象
    @MockBean
    private SampleAspect sampleAspect;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testgetdata() throws Exception {
        // 定义Mock的拦截方法行为:直接执行目标Controller方法,完全跳过原有切面逻辑
        when(sampleAspect.interceptor(any(ProceedingJoinPoint.class)))
                .thenAnswer(invocation -> {
                    ProceedingJoinPoint point = invocation.getArgument(0);
                    return point.proceed();
                });

        // 执行接口测试逻辑
        mockMvc.perform(get("/123"))
                .andExpect(status().isOk())
                .andExpect(content().string("hello"));
    }
}

该方案会完全屏蔽原有切面的所有逻辑,包括内部的数据库操作、对HandlerInterceptor实现类的调用,不需要额外处理切面的内部依赖。

方案2:仅Mock切面的内部依赖

如果你需要保留切面本身的逻辑,仅屏蔽数据库调用和HandlerInterceptor的真实执行,可以只Mock切面依赖的数据库操作类、以及对应的HandlerInterceptor实现类:

@WebMvcTest(SampleController.class)
class SampleControllerTest {
    // Mock切面内部调用的数据库操作Mapper/DAO
    @MockBean
    private OperateLogMapper operateLogMapper;
    // Mock切面内部调用的HandlerInterceptor实现类
    @MockBean
    private CustomHandlerInterceptor customHandlerInterceptor;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testgetdata() throws Exception {
        // 给Mock依赖定义默认返回值
        when(operateLogMapper.insert(any())).thenReturn(1);
        when(customHandlerInterceptor.preHandle(any(), any(), any())).thenReturn(true);

        // 执行测试即可,切面逻辑正常执行但不会触发真实外部调用
        mockMvc.perform(get("/123"))
                .andExpect(status().isOk());
    }
}

方案3:纯单元测试Controller

如果你的测试不需要启动Spring上下文,只是单元测试Controller的业务方法,直接手动实例化Controller调用方法即可,这种场景下切面根本不会被加载,自然不会触发拦截逻辑:

class SampleControllerTest {
    private final SampleController sampleController = new SampleController();

    @Test
    void testgetdata() {
        String result = sampleController.getdata("123");
        Assertions.assertEquals("hello", result);
    }
}

注意事项

如果出现Mock切面不生效的情况,检查测试类是否开启了AspectJ自动代理,Spring Boot默认已经开启,特殊场景可以手动在测试类上加@EnableAspectJAutoProxy注解即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 00:24:01