上一篇中讲到了安装和启动(跳转到mountebank安装、启动),该篇中记录一下如何进行简单的配置和使用,mountebank的模拟请求配置主要集中在stubs中,这里对stubs配置进行一个集中的说明。
stubs中主要组成是predicates和response,接下来会对这两项进行说明。
predicates
predicate的类型和示例
这里会介绍predicates的断言类型,mountebank提供了多种断言类型对请求进行断言。
-
equals
判断是否匹配。这个很简单,估计也将是使用率最高的断言。
The request field matches the predicate
-
deepEquals
深度匹配。当请求字段是对象的时候比较有用。
Performs nested set equality on the request field, useful when the request field is an object (e.g. the query field in http)
-
contains
请求包含内容。示例
{ "port": 4547, "protocol": "http", "stubs": [ { "responses": [{ "is": { "body": "first" } }], "predicates": [ { "contains": { "body": "first" } }, { "equals" : { "path":"/test" } } ] }, { "responses": [{ "is": { "body": "second" } }], "predicates": [ { "and" : [ { "contains": { "body": "second" } }, { "equals" : { "path":"/test" } } ] } ] }, { "responses": [{ "is": { "body": "third" } }], "predicates": [ { "contains": { "body": "third" } }, { "equals" : { "path":"/test" } } ] } ] }
请求
curl -i -X POST "http://localhost:4547/test" --data "third"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 02:31:07 GMT Transfer-Encoding: chunked third
-
startsWith & endsWith
这两个predicates见名知意,以XX开始和以XX结束。
{ "port": 4547, "protocol": "http", "stubs": [ { "responses": [{ "is": { "body": "startswith first" } }], "predicates": [ { "startsWith": { "query": {"first" : "first"} } }, { "equals" : { "path":"/test" } } ] }, { "responses": [{ "is": { "body": "endswith first" } }], "predicates": [ { "endsWith": { "query": {"first" : "first"} } }, { "equals" : { "path":"/test" } } ] } ] }
请求
curl -i -X GET "http://localhost:4547/test?first=firstxxxx"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 03:22:29 GMT Transfer-Encoding: chunked startswith first
请求
curl -i -X GET "http://localhost:4547/test?first=xxxfirst"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 03:22:37 GMT Transfer-Encoding: chunked endswith first
-
matches
该predicates支持正则表达式匹配。
{ "port": 4547, "protocol": "http", "stubs": [ { "responses": [{ "is": { "body": "startswith first" } }], "predicates": [ { "matches": { "query": {"first" : "^first.*"} } }, { "equals" : { "path":"/test" } } ] }, { "responses": [{ "is": { "body": "body contains 'matches'" } }], "predicates": [ { "matches": { "body": ".*matches\\d+.*" } }, { "equals" : { "path":"/test" } } ] } ] }
请求
curl -i -X GET "http://localhost:4547/test?first=firstasdfa"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 03:37:25 GMT Transfer-Encoding: chunked startswith first
请求
curl -i -X POST "http://localhost:4547/test" --data "somethignsmatches1234otherthings"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 03:43:02 GMT Transfer-Encoding: chunked body contains 'matches'
-
exists
匹配项存在。
官方示例
{ "port": 4551, "protocol": "http", "stubs": [ { "responses": [{ "is": { "body": "first response" } }], "predicates": [ { "exists": { "query": { "q": true, "search": false }, "headers": { "Accept": true, "X-Rate-Limit": false } } } ] }, { "responses": [{ "is": { "body": "second response" } }], "predicates": [ { "exists": { "method": true, "body": false } } ] }, { "responses": [{ "is": { "body": "third response" } }], "predicates": [ { "exists": { "body": true } } ] } ] }
请求
curl -i -H "Accept:text/html" -X GET "http://localhost:4551/test?q=13"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 06:27:11 GMT Transfer-Encoding: chunked first response
请求
curl -i -X GET "http://localhost:4551/test"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 06:33:25 GMT Transfer-Encoding: chunked second response
在这个例子中,如果使用请求
curl -i -X GET "http://localhost:4551/test"
, 依然会返回first response
, 原因在排查。 -
and & or & not
多predicate合并操作。
{ "port": 4551, "protocol": "http", "stubs": [ { "responses": [{ "is": { "body": "first response" } }], "predicates": [ { "and" : [ "exists": { "query": { "q": true, "search": false } }, { "matches" : { "body" : "and body" } } ] } ] }, { "responses": [{ "is": { "body": "second response" } }], "predicates": [ { "not" : [ "exists": { "query": { "q": true, "search": false } }, { "matches" : { "body" : "and body" } } ] } ] }, { "responses": [{ "is": { "body": "third response" } }], "predicates": [ { "or": [ { "startsWith" : { "body" : "or" } }, { "endsWith" : { "query" : "or" } } ] } ] } ] }
请求
curl -i -X POST "http://localhost:4551/test?q=134" --data "andbody"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 07:47:08 GMT Transfer-Encoding: chunked first response
请求
curl -i -X POST "http://localhost:4551/test?search=1234"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 07:48:27 GMT Transfer-Encoding: chunked second response
请求
curl -i -X POST "http://localhost:4551/test?q=1234or" curl -i -X POST "http://localhost:4551/test?q=1234" --data "or body"
响应
HTTP/1.1 200 OK Connection: close Date: Thu, 01 Mar 2018 07:51:41 GMT Transfer-Encoding: chunked third response
该请求示例中第二个请求不可使用
curl -i -X POST "http://localhost:4551/test" --data "or body"
因为会优先匹配第二个predicate。
predicate的匹配项和匹配规则
匹配项 | 类型 | 规则 |
---|---|---|
requestFrom | string | 这个参数没有尝试,看原文:The client socket, primarily used for logging and debugging. |
path | string | 请求的路径,不要带有请求参数 /test 是正确的,/test?q=1 是不正确的。 |
query | object | 请求的参数,例如: predicates类型是equals,"query":{"q":1};predicates的类型是exists, "query":{"q":true, "w":false} |
method | string | 请求方法。 |
headers | object | 请求头的headers信息。 |
body | string | POST请求的请求包体。 |
form | object | POST请求的form格式数据。例如:请求包体firstname=f&lastname=l,可以使用lastname来进行匹配 |
response
response类型
Response Type | 描述 |
---|---|
is | 对匹配的predicate做出响应的内容。原文:Merges the specified response fields with the response defaults . |
proxy | 使用代理。 原文:Proxies the request to the specified destination and returns the response. The response is saved and can be replayed on subsequent calls. |
inject | 使用function进行动态的注入。原文:Allows you to inject a JavaScript function to create the response object. |
本人对proxy
和inject
没有尝试,这里先对is
进行一些总结。
response配置项
配置项 | 类型 | 默认值 | 说明 |
---|---|---|---|
statusCode | int | 200 | http 响应的码值 |
headers | object | { "Connection": "close" } | http响应header头 |
body | string or object | "" | http响应包体 |
配置项的值可以使用 <%- stringify(filename, 'specifications/fields/fieldlist.json') %>
来引用其他文件,例如:
filedlist.json文件内容
{
"status": 200,
"message": "请求成功",
"data": {
"list": [{
"name": "项目简介",
"type": 0,
"url": "",
"value": "0.00%"
}, {
"name": "项目简介",
"type": 0,
"url": "",
"value": {
"rowTitle": ["", "", ""],
"rowsCount": 2,
"colsCount": 2,
"content": [
["", "", ""],
["", "", ""],
["", "", ""]
]
}
}]
}
}
is
的配置
"is": {
"statusCode" : 200,
"body": "<%- stringify(filename, 'specifications/fields/fieldlist.json') %>"
}
示例
{
"port": 4551,
"protocol": "http",
"stubs": [
{
"responses": [
{
"is": {
"statusCode" : 200,
"body": "first response",
"headers" : {
"Accept":"text/plain,text/html",
"Set-Cookie":"91token=1234",
"Access-Control-Allow-Headers":"Content-Type"
}
}
},
{
"is": {
"statusCode" : 200,
"body": { "status":"200", "data" : {"list":[]} },
"headers" : {
"Accept":"text/plain,text/html",
"Set-Cookie":"91token1=12341234",
"Access-Control-Allow-Headers":"Content-Type"
}
}
},
{
"is": {
"statusCode" : 404,
"headers" : {
"Accept":"text/plain,text/html",
"Set-Cookie":"91token2=12341234",
"Access-Control-Allow-Headers":"Content-Type"
}
}
}
],
"predicates": [
{
"equals": {
"path" : "/test"
}
}
]
}
]
}
请求
curl -i -X GET "http://localhost:4551/test"
上述请求依次执行三次,三次响应结果如下:
HTTP/1.1 200 OK
Accept: text/plain,text/html
Set-Cookie: token=1234
Access-Control-Allow-Headers: Content-Type
Connection: close
Date: Fri, 02 Mar 2018 06:27:23 GMT
Transfer-Encoding: chunked
first response
HTTP/1.1 200 OK
Accept: text/plain,text/html
Set-Cookie: token1=12341234
Access-Control-Allow-Headers: Content-Type
Connection: close
Date: Fri, 02 Mar 2018 06:27:27 GMT
Transfer-Encoding: chunked
{
"status": "200",
"data": {
"list": []
}
}
HTTP/1.1 404 Not Found
Accept: text/plain,text/html
Set-Cookie: token2=12341234
Access-Control-Allow-Headers: Content-Type
Connection: close
Date: Fri, 02 Mar 2018 06:27:28 GMT
Transfer-Encoding: chunked