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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:28:01