mountebank配置(一)

上一篇中讲到了安装和启动(跳转到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.

本人对proxyinject没有尝试,这里先对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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Python 面向对象Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对...
    顺毛阅读 4,207评论 4 16
  • 原文https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html...
    梁行之阅读 1,080评论 0 0
  • 我谁也不想理,只想收到你的消息
    潋潋up阅读 172评论 0 0
  • 小时候,爸妈买回来的苹果,我和弟弟一人一半,那个时候,我称之为平分。 后来,上学的时候,我和同桌拿把尺子精确的计算...
    喇叭下的小耳朵阅读 336评论 0 1