如何使用WireMock测试调用外部服务的Kafka消费者方法
我来帮你一步步搞定用WireMock模拟外部服务来测试你的Kafka消费者方法,核心思路就是让你的AssistanceManagerClient在测试环境中调用WireMock的模拟端点,而非真实的外部服务。下面是具体操作步骤:
步骤1:准备WireMock环境
你有两种方式启动WireMock:
独立Jar方式:下载WireMock的独立运行包(比如
wiremock-jre8-standalone-2.35.0.jar),然后执行命令启动:java -jar wiremock-jre8-standalone-2.35.0.jar --port 8080这里的
8080是WireMock监听的端口,你可以根据需要修改。Go库集成方式:如果想在测试代码里动态控制WireMock,推荐使用官方Go库
github.com/wiremock/go-wiremock,直接在测试代码中初始化和管理WireMock实例。
步骤2:配置WireMock Stub(模拟外部API的响应)
你需要针对SaveFxmWorklog接口的POST请求,配置两种核心场景的Stub:成功响应和失败响应。
场景1:模拟外部服务成功处理请求
如果用独立WireMock,在WireMock的mappings目录下创建save-fxm-worklog-success.json文件:
{ "request": { "method": "POST", "url": "/api/assistance-manager/save-fxm-worklog", // 替换为你实际的util.AssistanceManagerSaveFxmWorklog路径 "bodyPatterns": [ { "matchesJsonPath": "$.orderId" // 校验请求体包含orderId字段,可按需更精确匹配 } ] }, "response": { "status": 200, "jsonBody": { "HTTPStatusCode": 200, "Message": "Fxm worklog saved successfully" }, "headers": { "Content-Type": "application/json" } } }
场景2:模拟外部服务处理失败(比如500错误)
同样在mappings目录下创建save-fxm-worklog-error.json:
{ "request": { "method": "POST", "url": "/api/assistance-manager/save-fxm-worklog", "bodyPatterns": [ { "matchesJsonPath": "$.orderId" } ] }, "response": { "status": 500, "jsonBody": { "HTTPStatusCode": 500, "Message": "Failed to save fxm worklog" }, "headers": { "Content-Type": "application/json" } } }
如果用Go库集成方式,可以在测试代码中动态创建Stub(示例见步骤4)。
步骤3:修改测试环境配置
将你的amHost配置指向WireMock的地址,确保AssistanceManagerClient调用的是WireMock端点而非真实服务:
// 在测试初始化时设置 config.Client.SetString(amHost, "http://localhost:8080") // 端口和WireMock启动端口一致
步骤4:编写Go测试代码
现在可以针对ProcessMessage方法编写单元测试,覆盖成功和失败场景:
测试成功场景
func TestProcessMessage_Success(t *testing.T) { // 初始化WireMock客户端 wm := wiremock.NewClient("http://localhost:8080") defer wm.Reset() // 测试结束后重置所有Stub // 动态创建成功响应的Stub wm.StubFor(wiremock.Post(wiremock.URLPathEqualTo("/api/assistance-manager/save-fxm-worklog")). WithRequestBody(wiremock.MatchingJsonPath("$.orderId")). WillReturnResponse(wiremock.NewResponse(). WithStatus(200). WithHeader("Content-Type", "application/json"). WithBody(`{"HTTPStatusCode":200,"Message":"Success"}`))) // 初始化测试用的EventHandler handler := FxmWorklogEventHandler{ am: &AssistanceManagerClient{ hc: &yourHttpClientInstance, // 替换为你的HTTP客户端实例 }, } // 构造测试用的Kafka消息 testEvent := event.FxmWorklogEvent{OrderId: "test-order-001"} messageData, _ := json.Marshal(testEvent) kafkaMsg := kafka.Message{Data: messageData} // 调用待测试方法 status, err := handler.ProcessMessage(kafkaMsg) // 验证结果 assert.Equal(t, swgykafka.Success, status) assert.NoError(t, err) // 验证WireMock确实收到了请求 wm.Verify(wiremock.PostRequestedFor(wiremock.URLPathEqualTo("/api/assistance-manager/save-fxm-worklog")). WithRequestBody(wiremock.Containing("test-order-001"))) }
测试失败场景(外部服务返回500)
func TestProcessMessage_SoftFailure(t *testing.T) { wm := wiremock.NewClient("http://localhost:8080") defer wm.Reset() // 动态创建失败响应的Stub wm.StubFor(wiremock.Post(wiremock.URLPathEqualTo("/api/assistance-manager/save-fxm-worklog")). WithRequestBody(wiremock.MatchingJsonPath("$.orderId")). WillReturnResponse(wiremock.NewResponse(). WithStatus(500). WithHeader("Content-Type", "application/json"). WithBody(`{"HTTPStatusCode":500,"Message":"Failed"}`))) handler := FxmWorklogEventHandler{ am: &AssistanceManagerClient{ hc: &yourHttpClientInstance, }, } testEvent := event.FxmWorklogEvent{OrderId: "test-order-002"} messageData, _ := json.Marshal(testEvent) kafkaMsg := kafka.Message{Data: messageData} status, err := handler.ProcessMessage(kafkaMsg) // 验证结果:你的代码中返回SoftFailure时err为nil assert.Equal(t, swgykafka.SoftFailure, status) assert.NoError(t, err) // 验证请求到达WireMock wm.Verify(wiremock.PostRequestedFor(wiremock.URLPathEqualTo("/api/assistance-manager/save-fxm-worklog")). WithRequestBody(wiremock.Containing("test-order-002"))) }
关键注意点
- 确保WireMock的URL路径和
util.AssistanceManagerSaveFxmWorklog的实际路径完全一致,否则Stub不会匹配。 - 可以用
EqualToJson替代MatchingJsonPath,实现请求体的完全匹配,让测试更严谨。 - 如果想让测试完全自动化,可结合
testcontainers-go在测试中自动启动WireMock容器,无需手动启动WireMock服务。
内容的提问来源于stack exchange,提问作者Pankaj Kumar
相关产品推荐
相关产品推荐

