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

如何配置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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 05:10:42