如何在Spock中正确Mock JwtDecoder并测试AuthController集成测试
在Spock中Mock Spring Security的JwtDecoder正确姿势
针对你遇到的Spock测试中@MockBean无法替换JwtDecoder、导致请求第三方验证地址的问题,以下是几种可靠的解决方式:
方法一:使用Spock专属的@SpringBean注解
Spock的@SpringBean注解是为Spring Boot测试量身设计的,比Spring原生的@MockBean更适配Spock的Mock机制,能确保Mock实例正确替换容器中的原JwtDecoder Bean。
示例代码:
@SpringBootTest class AuthControllerSpec extends Specification { // 用@SpringBean替代@MockBean创建Mock实例 @SpringBean JwtDecoder jwtDecoder = Mock(JwtDecoder) def "测试认证接口时跳过第三方令牌验证"() { given: // 预设decode方法返回模拟的Jwt对象 def mockJwt = Mock(Jwt) jwtDecoder.decode(_) >> mockJwt when: // 调用目标接口,这里以MockMvc为例 def response = mockMvc.perform(get("/auth/me") .header("Authorization", "Bearer mock-token")) then: response.status.is2xxSuccessful() } }
方法二:手动通过配置类替换Bean
如果不想依赖Spock的专属注解,可以在测试类中嵌套配置类,手动注册Mock的JwtDecoder:
@SpringBootTest @Import(MockJwtDecoderConfig) class AuthControllerSpec extends Specification { @Autowired JwtDecoder jwtDecoder def "测试认证接口逻辑"() { given: def mockJwt = Mock(Jwt) jwtDecoder.decode("mock-token") >> mockJwt // 后续测试断言逻辑... } // 内部配置类,覆盖原有的JwtDecoder Bean @Configuration static class MockJwtDecoderConfig { @Bean JwtDecoder jwtDecoder() { return Mock(JwtDecoder) } } }
方法三:强制刷新测试上下文
如果测试上下文缓存导致Mock实例未被正确替换,可以添加@DirtiesContext注解强制每次测试重新加载上下文:
@SpringBootTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) class AuthControllerSpec extends Specification { @MockBean JwtDecoder jwtDecoder def "测试接口时Mock令牌解析"() { given: jwtDecoder.decode(_) >> Mock(Jwt) // 测试执行逻辑... } }
关键注意事项
- 确保测试类继承自Spock的
Specification,并正确引入spock-spring依赖 - 必须预设
JwtDecoder#decode方法的返回值,避免空指针或未模拟的方法调用异常 - 如果使用
TestRestTemplate或WebTestClient,请求中携带的Bearer令牌要与Mock方法的参数匹配
内容的提问来源于stack exchange,提问作者Akane
相关产品推荐
相关产品推荐

