Spring 6.1中如何用Mockito优雅Mock RestClient?
用Mockito优雅Mock RestClient的链式API
核心思路:RestClient的链式调用会生成多个中间对象(
RequestHeadersUriSpec、RequestHeadersSpec、ResponseSpec等),需要分层Mock这些对象,避免重复编写大量when().thenReturn()。步骤1:声明需要Mock的对象
用Mockito的@Mock注解(或Mockito.mock())创建所有链式调用涉及的对象:@Mock private RestClient restClient; @Mock private RestClient.RequestHeadersUriSpec<?> requestHeadersUriSpec; @Mock private RestClient.RequestHeadersSpec<?> requestHeadersSpec; @Mock private RestClient.ResponseSpec responseSpec;步骤2:Mock GET请求示例
针对完整的GET链式调用,依次Mock每个环节的返回值:// 模拟restClient.get()返回请求URI配置对象 when(restClient.get()).thenReturn(requestHeadersUriSpec); // 模拟指定URI后返回请求头配置对象 when(requestHeadersUriSpec.uri("/api/user/1")).thenReturn(requestHeadersSpec); // 模拟调用retrieve()后返回响应处理对象 when(requestHeadersSpec.retrieve()).thenReturn(responseSpec); // 模拟解析响应体为指定类型的结果 when(responseSpec.body(User.class)).thenReturn(new User(1L, "testUser"));步骤3:封装复用方法
把重复的Mock逻辑封装成工具方法,减少冗余代码:private <T> void mockRestClientGet(String uri, T mockResponse, Class<T> responseType) { when(restClient.get()).thenReturn(requestHeadersUriSpec); when(requestHeadersUriSpec.uri(uri)).thenReturn(requestHeadersSpec); when(requestHeadersSpec.retrieve()).thenReturn(responseSpec); when(responseSpec.body(responseType)).thenReturn(mockResponse); } // 测试时直接调用 mockRestClientGet("/api/user/1", new User(1L, "testUser"), User.class);步骤4:Mock POST请求示例
POST请求涉及body()方法,注意它返回的仍是RequestHeadersSpec,需要额外Mock:when(restClient.post()).thenReturn(requestHeadersUriSpec); when(requestHeadersUriSpec.uri("/api/user")).thenReturn(requestHeadersSpec); // 模拟设置请求体(支持任意对象入参) when(requestHeadersSpec.body(any(User.class))).thenReturn(requestHeadersSpec); when(requestHeadersSpec.retrieve()).thenReturn(responseSpec); // 模拟返回创建后的用户 when(responseSpec.body(User.class)).thenReturn(new User(2L, "newUser"));额外处理:Header/Query参数
如果代码中设置了Header或Query参数,只需Mock对应方法返回自身即可维持链式调用:// Mock Header设置 when(requestHeadersSpec.header(anyString(), anyString())).thenReturn(requestHeadersSpec); // Mock Query参数设置 when(requestHeadersUriSpec.queryParam(anyString(), anyObject())).thenReturn(requestHeadersUriSpec);
内容的提问来源于stack exchange,提问作者cloud_7
相关产品推荐
相关产品推荐

