@SpringBootTest结合WireMock本地正常,GitLab CI流水线执行失败
GitLab CI中SpringBootTest WireMock验证POST请求失败的排查与解决
问题场景
以下是一个基于Testcontainers启动RabbitMQ容器的Spring Boot集成测试,核心流程为:
- 向目标队列发送消息
- 拒绝消息使其移入对应死信队列
- 验证死信队列存在消息
- 验证向RocketChat的WireMock实例发起了POST请求
测试代码如下:
@RegisterExtension protected static WireMockExtension rocketChatWireMock = WireMockExtension.newInstance() .options(wireMockConfig().dynamicPort()) .build(); @DynamicPropertySource static void configureRocketChatProperties(DynamicPropertyRegistry registry) { registry.add("rocket-chat-url", () -> rocketChatWireMock.baseUrl()); } @Test void shouldSendAlertToRocketChat() throws JSONException { final int retryCount = 3; final String payload = buildPayload(); rocketChatWireMock.stubFor(post(anyUrl()).willReturn(ok())); sendMessage("my-routing-key", payload, retryCount); waitUntilMessageIsPresent("my-queue"); rejectMessage("my-queue"); waitUntilMessageIsPresent("parking-lot-queue"); final Message parkingLotMessage = rabbitTemplate.receive("parking-lot-queue"); assertThat(parkingLotMessage).isNotNull(); await().untilAsserted(() -> rocketChatWireMock.verify(postRequestedFor(anyUrl()))); }
该测试在本地运行正常,但在GitLab CI流水线执行时始终失败,报错:
Caused by: com.github.tomakehurst.wiremock.client.VerificationException: Expected at least one request matching: { "method" : "POST" }
排查与解决思路
1. 检查CI环境的网络连通性
- 确认Spring Boot应用是否正确获取到WireMock的地址:在
configureRocketChatProperties方法中添加日志,打印rocketChatWireMock.baseUrl()的值,查看CI日志中是否为正确的WireMock服务地址。 - 排查GitLab CI Runner的网络配置:如果使用Docker in Docker模式,确保容器间网络互通,没有防火墙或网络隔离规则阻止应用向WireMock发起请求。
2. 调整异步流程的等待时长
CI环境资源通常比本地紧张,异步逻辑(消息重试、死信队列处理、RocketChat请求触发)耗时更长:
- 延长
await()的超时时间,避免验证提前执行:await().atMost(Duration.ofMinutes(1)).untilAsserted(() -> rocketChatWireMock.verify(postRequestedFor(anyUrl()))); - 检查
waitUntilMessageIsPresent方法的实现,确保其等待时长足够覆盖CI环境下的消息处理延迟。
3. 提前配置WireMock Stub
确保WireMock的Stub在应用启动前就准备完成,避免因为Stub配置晚于请求发起导致无匹配:
@BeforeAll static void setupWireMock() { rocketChatWireMock.stubFor(post(anyUrl()).willReturn(ok())); }
4. 验证RabbitMQ重试逻辑的执行周期
测试中设置了retryCount=3,需确认CI环境下RabbitMQ的重试间隔与本地一致,且等待时长覆盖整个重试周期,避免在重试未完成时就开始验证WireMock请求。
5. 调试WireMock请求接收情况
在CI中添加调试日志,查看WireMock实际收到的请求:
// 在验证前打印所有收到的请求 System.out.println("WireMock received requests: " + rocketChatWireMock.getAllServeEvents());
通过日志确认是否有请求到达WireMock,以及请求的方法、URL是否符合预期。
内容的提问来源于stack exchange,提问作者Robert Strauch
相关产品推荐
相关产品推荐

