使用复杂对象编写 Given/Then/When 规范
Writing Given/Then/When specs with complex objects
我正在尝试在完全支持的情况下使用 GWT
规范,但其 official documentation 的示例有点简单。
在 SO 中搜索我发现了这个问题:
- Specs2 - How to define complex objects for Given/When/Then steps
但它太老了(3 年),我认为 specs2
中 GWT
的做法已经改变。
到目前为止我有这个简单的测试:
class FlowCollectorSpec extends Specification
with GWT
with StandardRegexStepParsers { def is = s2"""
Given a API route to get flows ${apiCaller.start}
Given an access to the API URL: http://192.168.56.102:8080/stats/flow/
When getting flow stats for a switch with id: 1
Then status code should be: 200 ${apiCaller.end}
"""
val anAPIUri = readAs(".*: (.*)$").and((s: String) => s)
val apiCaller =
Scenario("apiCaller").
given(aString).
given(anInt).
when(anAPIUri) {case url :: dpid :: _ => FlowCollector.getSwitchFlows(dpid)}.
andThen(anInt) {case expected :: actual :: _ => actual.code must_== expected}
}
如何在 Given 语句中指定复杂对象?像这样:
Given a Json response: ${jsonResponse}
我终于想到了一个解决方案,我不知道这样做是否正确,但目前它正在工作:
class FlowCollectorSpec extends Specification
with GWT
with StandardRegexStepParsers { def is = s2"""
Given a API route to get flows ${connectTest.start}
Given an access to the API URL: http://192.168.56.102:8080/stats/flow/
When getting flow stats for a switch with id: 1
Then status code should be: 200 ${connectTest.end}
Retrieving values ${gettingValues.start}
Given an api call response: {"1": [{"actions": ["OUTPUT:CONTROLLER"], "idle_timeout": 0, "cookie": 0, "packet_count": 1212, "hard_timeout": 0, "byte_count": 72720, "duration_sec": 432, "duration_nsec": 903000000, "priority": 65535, "length": 96, "flags": 0, "table_id": 0, "match": {"dl_type": 35020, "dl_dst": "01:80:c2:00:00:0e"}}, {"actions": ["OUTPUT:CONTROLLER"], "idle_timeout": 0, "cookie": 0, "packet_count": 49, "hard_timeout": 0, "byte_count": 3890, "duration_sec": 432, "duration_nsec": 938000000, "priority": 0, "length": 80, "flags": 0, "table_id": 0, "match": {}}]}
When extracting key: packet_count
Then a field look up should return: true ${gettingValues.end}
"""
val stepParser = readAs(".*: (.*)$").and((s: String) => s)
val jsonExtractor = readAs(".+?: (.*)").and((s:String) => JsonParser(s).asJsObject)
val aJsonKey = aString
val connectTest =
Scenario("connectTest").
given(aString).
given(anInt).
when(stepParser) {case url :: dpid :: _ => FlowCollector.getSwitchFlows(dpid)}.
andThen(anInt) {case expected :: actual :: _ => actual.code must_== expected}
val gettingValues =
Scenario("Getting Values").
given(jsonExtractor).
when(aJsonKey) { case key :: json :: _ => json.fields contains key}.
andThen(){
case expected :: exists :: _ =>
if (expected == "true") exists must_== true
else exists must_==false
}
}
如果你的数据很复杂,无法在一行中显示,你可以简单地写
class FlowCollectorSpec extends Specification
with GWT
with StandardRegexStepParsers { def is = s2"""
Given a API route to get flows ${apiCaller.start}
Given an access to the API URL: http://192.168.56.102:8080/stats/flow/
Given some complex data
When getting flow stats for a switch with id: 1
Then status code should be: 200 ${apiCaller.end}
"""
val anAPIUri = readAs(".*: (.*)$").and((s: String) => s)
val apiCaller =
Scenario("apiCaller").
given(aString).
given(complexData).
given(anInt).
when(anAPIUri) { case url :: Json(j) :: dpid :: _ => FlowCollector.getSwitchFlows(dpid) }.
andThen(anInt) { case expected :: actual :: _ => actual.code must_== expected }
val complexData = readAs(".*").andThen(_ => Json("some json"))
case class Json(value: String)
object FlowCollector {
def getSwitchFlows(dpid: Int) = FlowResult(code = 200)
}
case class FlowResult(code: Int)
}
否则你的解决方案就是正确的。
我正在尝试在完全支持的情况下使用 GWT
规范,但其 official documentation 的示例有点简单。
在 SO 中搜索我发现了这个问题:
- Specs2 - How to define complex objects for Given/When/Then steps
但它太老了(3 年),我认为 specs2
中 GWT
的做法已经改变。
到目前为止我有这个简单的测试:
class FlowCollectorSpec extends Specification
with GWT
with StandardRegexStepParsers { def is = s2"""
Given a API route to get flows ${apiCaller.start}
Given an access to the API URL: http://192.168.56.102:8080/stats/flow/
When getting flow stats for a switch with id: 1
Then status code should be: 200 ${apiCaller.end}
"""
val anAPIUri = readAs(".*: (.*)$").and((s: String) => s)
val apiCaller =
Scenario("apiCaller").
given(aString).
given(anInt).
when(anAPIUri) {case url :: dpid :: _ => FlowCollector.getSwitchFlows(dpid)}.
andThen(anInt) {case expected :: actual :: _ => actual.code must_== expected}
}
如何在 Given 语句中指定复杂对象?像这样:
Given a Json response: ${jsonResponse}
我终于想到了一个解决方案,我不知道这样做是否正确,但目前它正在工作:
class FlowCollectorSpec extends Specification
with GWT
with StandardRegexStepParsers { def is = s2"""
Given a API route to get flows ${connectTest.start}
Given an access to the API URL: http://192.168.56.102:8080/stats/flow/
When getting flow stats for a switch with id: 1
Then status code should be: 200 ${connectTest.end}
Retrieving values ${gettingValues.start}
Given an api call response: {"1": [{"actions": ["OUTPUT:CONTROLLER"], "idle_timeout": 0, "cookie": 0, "packet_count": 1212, "hard_timeout": 0, "byte_count": 72720, "duration_sec": 432, "duration_nsec": 903000000, "priority": 65535, "length": 96, "flags": 0, "table_id": 0, "match": {"dl_type": 35020, "dl_dst": "01:80:c2:00:00:0e"}}, {"actions": ["OUTPUT:CONTROLLER"], "idle_timeout": 0, "cookie": 0, "packet_count": 49, "hard_timeout": 0, "byte_count": 3890, "duration_sec": 432, "duration_nsec": 938000000, "priority": 0, "length": 80, "flags": 0, "table_id": 0, "match": {}}]}
When extracting key: packet_count
Then a field look up should return: true ${gettingValues.end}
"""
val stepParser = readAs(".*: (.*)$").and((s: String) => s)
val jsonExtractor = readAs(".+?: (.*)").and((s:String) => JsonParser(s).asJsObject)
val aJsonKey = aString
val connectTest =
Scenario("connectTest").
given(aString).
given(anInt).
when(stepParser) {case url :: dpid :: _ => FlowCollector.getSwitchFlows(dpid)}.
andThen(anInt) {case expected :: actual :: _ => actual.code must_== expected}
val gettingValues =
Scenario("Getting Values").
given(jsonExtractor).
when(aJsonKey) { case key :: json :: _ => json.fields contains key}.
andThen(){
case expected :: exists :: _ =>
if (expected == "true") exists must_== true
else exists must_==false
}
}
如果你的数据很复杂,无法在一行中显示,你可以简单地写
class FlowCollectorSpec extends Specification
with GWT
with StandardRegexStepParsers { def is = s2"""
Given a API route to get flows ${apiCaller.start}
Given an access to the API URL: http://192.168.56.102:8080/stats/flow/
Given some complex data
When getting flow stats for a switch with id: 1
Then status code should be: 200 ${apiCaller.end}
"""
val anAPIUri = readAs(".*: (.*)$").and((s: String) => s)
val apiCaller =
Scenario("apiCaller").
given(aString).
given(complexData).
given(anInt).
when(anAPIUri) { case url :: Json(j) :: dpid :: _ => FlowCollector.getSwitchFlows(dpid) }.
andThen(anInt) { case expected :: actual :: _ => actual.code must_== expected }
val complexData = readAs(".*").andThen(_ => Json("some json"))
case class Json(value: String)
object FlowCollector {
def getSwitchFlows(dpid: Int) = FlowResult(code = 200)
}
case class FlowResult(code: Int)
}
否则你的解决方案就是正确的。