如何配置WireMock Stub被调用一次后自动移除或禁用?
WireMock 单次调用后自动移除Stub的优雅实现方案
我用以下代码在WireMock中创建了一个Stub:
getWiremock().stubFor(get(urlMatching("/rs-queue/messages.*")) .willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", "application/json") .withBody(fromObjectToString(queueMessageItem)) ));
我希望这个Stub在被调用一次后自动移除或禁用,但在WireMock文档里没找到相关示例。我曾考虑过启动新线程执行以下代码来实现:
RequestPatternBuilder requestPatternBuilder = postRequestedFor(urlEqualTo(url)) .withRequestBody(new EqualToPattern(fromObjectToString(queueMessageItem))); Awaitility.waitAtMost(Duration.of(1, ChronoUnit.MINUTES)) .pollInterval(Duration.of(3, ChronoUnit.SECONDS)) .until(() -> { try { verify(moreThanOrExactly(1), requestPatternBuilder); getWiremock().removeStubMapping(stubMapping.getUuid()); } catch (VerificationException exception) { return false; } return true; });
但这个方案太繁琐,不够优雅,应该有更简洁的WireMock配置方式,请问有什么可行方案?
方案1:使用WireMock原生调用次数限制(推荐,WireMock 2.27.0+)
WireMock从2.27.0版本开始支持直接为Stub设置调用次数上限,超过次数后Stub会自动失效,无需额外的线程或验证逻辑,是最简洁的原生解决方案:
StubMapping stub = getWiremock().stubFor(get(urlMatching("/rs-queue/messages.*")) .willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", "application/json") .withBody(fromObjectToString(queueMessageItem)) ) // 设置仅允许调用1次,调用后自动失效 .withLimit(new StubInvocationLimit(1)));
方案2:使用Scenario状态切换(适配低版本WireMock)
如果你的WireMock版本低于2.27.0,可以通过Scenario功能模拟"单次有效"的状态逻辑:
// 初始化单次调用的Scenario,初始状态为未调用 getWiremock().stubFor(get(urlMatching("/rs-queue/messages.*")) .inScenario("SingleCallStub") .whenScenarioStateIs(Scenario.STARTED) .willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", "application/json") .withBody(fromObjectToString(queueMessageItem)) ) // 调用后切换到已调用状态 .willSetStateTo("Called")); // 添加匹配相同路径但状态为已调用的Stub,返回404或其他你需要的响应(相当于禁用原Stub) getWiremock().stubFor(get(urlMatching("/rs-queue/messages.*")) .inScenario("SingleCallStub") .whenScenarioStateIs("Called") .willReturn(aResponse().withStatus(404)));
内容的提问来源于stack exchange,提问作者alexey kurbatov
相关产品推荐
相关产品推荐

