WireMock之定义状态控制返回
基本语法
可以定义一个场景,然后通过状态来控制每次请求返回的内容
基本语法,初始状态总是为Started
XXX.inScenario("Scenario") .whenScenarioStateIs("Started") .willSetStateTo("NewStatus")); XXX.inScenario("Scenario") .whenScenarioStateIs("NewStatus")
json样例
{ "scenarioName": "Scenario", "requiredScenarioState": "STARTED", "request": { "method": "GET", "url": "/xxx" }, "response": { "status": 200, "body" : "xxxxxxxxxxxxxxx" } } { "scenarioName": "Scenario", "requiredScenarioState": "Started", "newScenarioState": "NewStatus", "request": { .... }
举个例子
场景1,比如想让同一个接口调用多次,每次返回不同的值,较多见于重试逻辑
@BeforeClass public void setUp() throws FileNotFoundException, IOException { WireMock.configureFor("127.0.0.1", 8080); wireMockServer = new WireMockServer(wireMockConfig()); log.info("START WIREMOCK"); wireMockServer.start(); } public void setMyRule() { stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("Started") .willReturn(aResponse().withStatus(200).withBody("api add fail first")) .willSetStateTo("step2")); stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("step2") .willReturn(aResponse().withStatus(200).withBody("api add suc second"))); } @Test public void testForMock() { setMyRule(); String response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); }
按照设定,第一次返回fail,第二次返回suc
[INFO ]23:38:17, [Class]MockCliTest, [Method]setUp, START WIREMOCK [INFO ]23:38:18, [Class]MockCliTest, [Method]testForMock, GET RESP:api add fail first [INFO ]23:38:18, [Class]MockCliTest, [Method]testForMock, GET RESP:api add suc second PASSED: testForMock
稍微复杂点。模拟一个post add操作使get的结果加1,使用如下的设置场景状态的方法:
public void setMyRule() { stubFor(get(urlEqualTo("/api/pod")) .willReturn(aResponse().withStatus(200).withBody("get empty list"))); stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("Started") .willReturn(aResponse().withStatus(200).withBody("api add suc,first")) .willSetStateTo("step2")); stubFor(get(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("Start") .willReturn(aResponse().withStatus(200).withBody("get empty list")) ); stubFor(get(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("step2") .willReturn(aResponse().withStatus(200).withBody("get 1 node")) .willSetStateTo("step3")); stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("step3") .willReturn(aResponse().withStatus(200).withBody("api add suc,second")) .willSetStateTo("step4")); stubFor(get(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("step4") .willReturn(aResponse().withStatus(200).withBody("get 2 node")) ); } @Test public void testForMock() { String response; setMyRule(); response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); response=HttpUtil.get("http://127.0.0.1:8080/api/pod",null,"UTF-8"); log.info("GET RESP:"+response); response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); response=HttpUtil.get("http://127.0.0.1:8080/api/pod",null,"UTF-8"); log.info("GET RESP:"+response); }
结果如下:
[INFO ]20:20:39, [Class]MockCliTest, [Method]setUp, START WIREMOCK [INFO ]20:20:39, [Class]MockCliTest, [Method]testForMock, GET RESP:api add suc,first [INFO ]20:20:39, [Class]MockCliTest, [Method]testForMock, GET RESP:get 1 node [INFO ]20:20:39, [Class]MockCliTest, [Method]testForMock, GET RESP:api add suc,second [INFO ]20:20:39, [Class]MockCliTest, [Method]testForMock, GET RESP:get 2 node PASSED: testForMock
优先级的问题
根据最新最优先的原则,总是最新设置的规则生效(包括带状态属性和不带状态属性的规则),比如最新的规则是不带状态属性的,那么之前的那些都不生效
若实际设置的时候是如下交叉的顺序
stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("Started").willReturn(aResponse().withStatus(200).withBody("api add fail first")).willSetStateTo("step2")); stubFor(post(urlEqualTo("/api/pod")).willReturn(aResponse().withStatus(200).withBody("api add fail first"))); stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("step2").willReturn(aResponse().withStatus(200).withBody("api add suc second")));
结果是都输出第一个匹配的结果,所以保证顺序很重要
重置
通过WireMock.resetAllScenarios()
或post空请求到http://<host>:<port>/__admin/scenarios/reset.
可以将场景的状态重置为初始的start状态,如下
public void setMyRule() { stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("Started") .willReturn(aResponse().withStatus(200).withBody("api add fail first")) .willSetStateTo("step2")); stubFor(post(urlEqualTo("/api/pod")).inScenario("podtest").whenScenarioStateIs("step2") .willReturn(aResponse().withStatus(200).withBody("api add suc second"))); } @Test public void testForMock() { String response; setMyRule(); response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); //RESET WireMock.resetAllScenarios(); response=HttpUtil.post("http://127.0.0.1:8080/api/pod",""); log.info("GET RESP:"+response); }
状态被重置为初始状态
[INFO ]20:30:28, [Class]MockCliTest, [Method]setUp, START WIREMOCK [INFO ]20:30:29, [Class]MockCliTest, [Method]testForMock, GET RESP:api add fail first [INFO ]20:30:29, [Class]MockCliTest, [Method]testForMock, GET RESP:api add suc second [INFO ]20:30:29, [Class]MockCliTest, [Method]testForMock, GET RESP:api add fail first PASSED: testForMock