调用其他微服务时如何为当前微服务编写Integration Test(集成测试)
跨服务依赖无法本地运行时的集成测试方案
方案1:使用消费者驱动契约测试(最推荐)
该方案不需要依赖真实的ServiceB运行,即可验证ServiceA的调用逻辑正确性,非常适合微服务跨团队协作场景:
- 先明确你与ServiceB的交互契约:包括请求路径
/{id}/works、PUT请求方法、请求头携带accessToken、Content-Type为application/json、请求体为UGT对象序列化后的JSON、成功响应为200状态码 - 用契约测试框架(如Spring Cloud Contract、Pact JVM)根据契约自动生成ServiceB的模拟桩,IT测试时直接指向模拟桩运行即可
- 断言验证点:URL拼接逻辑正确、请求参数序列化正常、非200响应/网络异常时日志正常输出
方案2:指向测试环境运行隔离集成测试
如果团队已有统一测试环境部署了可用的ServiceB,可直接将IT运行环境指向测试环境:
- 在ServiceA的测试配置文件中单独配置测试环境的
ServiceB_Baseurl,本地运行IT时自动加载该配置,不使用本地地址 - 测试用例前置操作:提前调用ServiceB的创建接口在测试环境生成可用的测试id,或者预置固定的测试id数据
- 测试执行完成后执行清理操作,删除测试生成的脏数据,避免影响其他测试
- 可扩展断言逻辑:除了验证本地代码的执行逻辑,还可以新增调用ServiceB的查询接口,确认数据更新符合预期
方案3:分层验证降低依赖影响
如果前两个方案暂时无法落地,可以用分层测试的方式覆盖核心逻辑:
第一层:调用逻辑单元测试
Mock掉httpUtil依赖,覆盖所有分支逻辑,示例代码如下:
@ExtendWith(MockitoExtension.class) public class ServiceAClientTest { @Mock private HttpUtil httpUtil; @InjectMocks private YourService yourService; @Test public void testAddUToG_success() throws Exception { UGT ugt = new UGT(); String accessToken = "test_token"; String expectedUrl = ServiceB_Baseurl + "/test_id/works"; // 模拟200响应 HttpResponse mockResponse = Mockito.mock(HttpResponse.class); StatusLine mockStatusLine = Mockito.mock(StatusLine.class); Mockito.when(mockStatusLine.getStatusCode()).thenReturn(HttpStatus.SC_OK); Mockito.when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); Mockito.when(httpUtil.putRequest(eq(expectedUrl), eq(accessToken), eq(ContentType.APPLICATION_JSON.toString()), anyString())) .thenReturn(mockResponse); yourService.addUToG(ugt, accessToken); // 验证http请求是否按预期调用 Mockito.verify(httpUtil, times(1)).putRequest(anyString(), anyString(), anyString(), anyString()); } @Test public void testAddUToG_fail_non200Response() throws Exception { // 模拟返回非200的场景,验证warn日志是否正常输出 } @Test public void testAddUToG_exception() throws Exception { // 模拟http请求抛出异常的场景,验证异常捕获和日志输出逻辑 } }
第二层:窄面集成测试
仅初始化HTTP客户端相关配置,不启动全量服务上下文,直接调用测试环境ServiceB的接口验证连通性、鉴权逻辑和参数正确性,大幅降低测试启动成本。
内容的提问来源于stack exchange,提问作者The_new_coder
相关产品推荐
相关产品推荐

