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

 

更多详情见http://wiremock.org/stateful-behaviour.html

 
posted @ 2015-07-19 00:14  opama  阅读(1690)  评论(0编辑  收藏  举报