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

Spring Cloud Contract测试因拦截器preHandle设置请求属性失败

问题1:Spring Cloud Contract测试中拦截器无法获取客户端ID的解决方案

核心原因

你的拦截器在preHandle中调用的认证服务在SCC测试环境下未被存根,导致返回null,进而无法设置到HttpServletRequest中。直接存根HttpServletRequest.getAttribute()无效,因为拦截器是先设置属性,控制器才会读取,问题根源在认证服务的调用而非request的读取逻辑。

正确解决方案:模拟认证服务

不要硬编码ID或存根业务服务,而是直接模拟拦截器依赖的认证服务,让它返回预设的客户端ID,这样拦截器就能正常完成逻辑,控制器也能拿到正确的参数。

示例代码

假设你的认证服务接口是AuthService,在测试类中使用@MockBean模拟它:

import org.springframework.boot.test.mock.mockito.MockBean;
import static org.mockito.Mockito.when;

@SpringBootTest
@AutoConfigureMockMvc
public class YourControllerContractTest {

    @MockBean
    private AuthService authService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testContractEndpoint() throws Exception {
        // 模拟认证服务返回预设的客户端ID
        when(authService.getClientId(any(HttpServletRequest.class))).thenReturn("test-client-123");

        // 执行SCC测试请求
        mockMvc.perform(get("/your-endpoint"))
               .andExpect(status().isOk());
    }
}

额外注意点

  • 确保拦截器在测试上下文被正确加载:如果使用@WebMvcTest,需要手动注册拦截器(通过@TestConfiguration),因为@WebMvcTest默认只加载指定控制器和相关组件,不会自动加载所有拦截器。
  • 避免排除拦截器的测试配置:检查测试类的@SpringBootTest或@WebMvcTest是否有excludeFilters排除了拦截器所在的包。

问题2:Spring Cloud Contract(SCC)测试的执行逻辑

SCC测试分为生产者侧和消费者侧,两者执行逻辑差异明显:

生产者侧测试

  • 目的:验证你的服务实际行为是否符合契约定义。
  • 执行逻辑:启动完整的Spring应用上下文,加载所有真实组件(包括拦截器、业务服务、仓库等)。
  • 数据库相关:如果你的仓库依赖数据库,默认会使用配置的测试数据库(比如H2内存库,需在application-test.yml中配置),会执行真实的CRUD操作;如果未配置数据库,会因数据源不可用直接失败。
  • 模拟规则:不会自动模拟内部组件(如仓库),除非你手动用@MockBean或Mockito进行模拟。

消费者侧测试

  • 目的:验证你的服务(作为消费者)是否能正确与生产者服务(通过契约存根)交互。
  • 执行逻辑:
    1. 启动消费者的Spring上下文,加载自身的组件(拦截器、业务服务、仓库等)。
    2. 通过Stub Runner加载生产者的契约存根,将对生产者服务的调用转发到存根(而非真实服务)。
  • 内部组件处理:消费者自身的仓库、业务服务等默认会执行真实逻辑,不会自动生成模拟返回值。如果这些组件依赖外部资源(如数据库),必须配置测试环境的依赖(如H2),否则会因资源不可用失败。只有当你手动模拟这些组件时,才会返回预设的模拟值。

关于“参数正确就生成模拟返回值”的误解

SCC不会自动为你的内部组件生成模拟返回值,这个逻辑是Mockito等测试框架的功能。你看到的“仓库方法返回值”,要么是测试数据库返回的真实数据,要么是你之前通过@MockBean配置的模拟值,和SCC本身无关。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:32:18