美文网首页
WireMock 搭建本地测试服务及使用案例

WireMock 搭建本地测试服务及使用案例

作者: ErHu丶 | 来源:发表于2017-12-18 17:19 被阅读968次

    入门

    什么是WireMock, 我的理解是模拟后端服务。由于前端开发一般先于后端,所以为了能够模拟比较真实的后端借口服务,就需要搭建Mock Service,这种模拟跟写假数据是有区别的,虽然数据都是假的,但是Mock Service可以拥有真实的网络请求环境,也可以动态的修改获取数据。(这是我的理解~ 我是小白哈,欢迎指正~)

    研究了一天,基本了解使用后觉得WireMock还是挺简单的,运行一下jar包就可以搭建服务器了。下面我就整理下小白学习流程😂~

    Mac想要运行jar文件需要配置java环境,jdk下载地址,安装好后就可以运行jar文件啦~ (如果遇到java路径问题可能是环境变量没配好,上网查查~)

    回到WireMock , WireMock Jar 包在这里下载,这里我们下载的是wiremock-standalone,记住这个standalone单词 ,也就是一种可以独立运行的“模式”,下载完成后用终端cd到目录下运行

    // 请注意你下载的版本号和名称,不要盲目复制运行
    java -jar wiremock-standalone-2.1.10.jar -port 7777
    

    -port 是选择运行端口,默认是:8080,如果8080端口被暂用了还是用其他的吧~
    如果启动成功了会出现WireMock的图案:


    启动成功图

    这时候该文件目录下会出现两个文件夹
    mappings:可以理解成专门定义request请求的地方,你需要把你需要请求的所有request请求先在这里先定义。每一次改动都需要重启WireMock服务!!!(如果服务已经启动了,先:control + c 停止服务,再重新运行上面的代码运行jar文件并且出现成功图案即可),如果发现没有成功的图,可能是mappings下的某个request文件出错了,重新检查下~
    __files:可以理解成存放response请求body的地方,在request中设置响应体文件名称,服务会对应找到__files下的这个文件作为response返回~

    举个🌰:
    mappings 文件夹下我创建一个abc.json格式的请求(名称随意起),内容如下:
    请求方式GET,路径是/api,对应的response是个文件,文件名为two.json,类型为json,

    {
      "request": {
          "method": "GET",
          "urlPath": "/api"
      },
      "response": {
          "status": 200,
          "bodyFileName": "two.json",
          "headers": {
              "Content-Type": "application/json"
          }
      }
    }
    
    

    保存后,重启WireMock服务,成功后在浏览器中打开地址,http://localhost:7777/api 别忘了端口号呦~

    image.png
    该错误是正常的,因为我们返回的是内容是two.json的文件,可是我们并没有写这个文件,下面我们只要在__files中创建这个json文件即可
    {
        "equalToJson" : "{ \"name\": \"new product\", \"creator\": \"tester\", \"createTime\": \"2015-09-07\" }", 
        "jsonCompareMode": "LENIENT"
    }
    

    __files 文件夹内的改动不需要重启服务,保存即可,再次看看浏览器页面~ 完工啦~


    image.png

    当然,你也可以不用创建这个文件,直接在request中将bodyFileName改成直接body写出这个json也是可以的

    {
     {
      "request": {
          "method": "GET",
          "urlPath": "/api"
      },
      "response": {
          "status": 200,
          "body": "{ \"id\": 1, \"name\": \"new product\", \"creator\": \"tester\", \"createTime\": \"2015-09-07\" }",
          "headers": {
              "Content-Type": "application/json"
          }
      }
    }
    

    是不是很简单方便,当然,POST请求也是可以的, XML格式请求也是可以的~

    进阶一:

    以上是一种非常简单的形式,数据都是写死的,那么如果想要加入参数怎么办呢?
    参数的传递需要对WireMock进行扩展,也就是需要另一种jar包支持:wiremock-body-transformer,开发者描述中找到standalone模式对应的地方可以看到它的使用介绍:
    首先下载扩展包 [Download the body transformer extension jar file here.]
    如果还没有WireMock的“基础包” 点击这里下载 wiremock-standalone-2.1.10.jar ,有的话就不用下了。
    然后将两个jar包放在一个文件夹下运行

    // 请注意你下载的这两个jar包的版本号和名称,不要盲目复制运行
    java -cp "wiremock-body-transformer-1.1.6.jar:wiremock-standalone-2.3.1.jar" com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --verbose --extensions com.opentable.extension.BodyTransformer -port 7777
    

    运行成功后就可以写借口了。先创建一个GET请求的request,格式是json,文件名随意,内容如下:

    {
        "request": {
            "method": "GET",
            "urlPath": "/transform"
        },
        "response": {
            "status": 200,
            "body": "{\"responseName\": \"$(name)\"}",
            "headers": {
                "Content-Type": "application/json"
            },
            "transformers": ["body-transformer"]
        }
    }
    

    可以看到其中有个特别的字段是$(name),这个就是GET请求中的参数名称,用$()包裹,保存后重启服务,在浏览器中打开

    image.png
    参数获取成功~

    下面我们试下XML格式,和POST请求的效果:
    依然是先创建request,格式是json,文件名随意,内容如下:

    {
        "request": {
            "method": "POST",
            "urlPath": "/transform/post"
        },
        "response": {
            "status": 200,
            "body": "<node><to>$(body.node.to)</to><from>$(body.node.from)</from><heading><order><orderNo>$(body.node.heading.order.orderNo)</orderNo><orderNo2>$(body.node.heading.order.orderNo2)</orderNo2></order></heading></node>",
            "headers": {
                "Content-Type": "text/xml"
            },
            "transformers": ["body-transformer"]
        }
    }
    

    可以看到在返回内容的body中,我们返回的是xml格式的内容,而且$()中是支持点语法的,这样我们就可以访问的请求体中的内容了,接下来我们需要发送这个post请求,需要用到Postman 来模拟post请求:

    因为模拟xml格式的请求, 所以我们设置post请求体中也为xml格式,来看下效果

    image.png

    成功拿到数据,可以理解$(body)是能够拿到response下的body内容的,既然支持点语法,就可以很轻松访问其他节点~

    如果觉得在response中将body以字符串的形式表达很不直观的话,我们可以用文件的形式去写~
    依然是先创建request,格式是json,文件名随意,内容如下:

    {
        "request": {
            "method": "POST",
            "urlPath": "/transform/post/file"
        },
        "response": {
            "status": 200,
            "bodyFileName": "test-post-file-body.vm",
            "headers": {
                "Content-Type": "text/xml"
            },
            "transformers": ["body-transformer"]
        }
    }
    
    

    我将原先写在response中的body内容替换为bodyFileName,并且指明文件名,在 __files 文件夹中创建 test-post-file-body.vm这个文件,内容就是之前response中body中的内容:

    <node>
        <to>$(body.node.to)</to>
        <from>$(body.node.from)</from>
        <heading>
            <order>
                <orderNo>$(body.node.heading.order.orderNo)</orderNo>
                <orderNo2>$(body.node.heading.order.orderNo2)</orderNo2>
            </order>
        </heading>
    </node>
    

    这样写是很可观的,一目了然~
    重启运行后的效果当然结果跟之前也是一样的,这里就不展示了。

    至此,参数获取完结~ 怎么样?还是蛮简单的吧

    进阶二

    再想想, 以上所掌握的方法依然不满足现实所需,能不能写一些判断语句在里面呢,类似这种

    <orderNo>$(body.orderNo > 0 ? body.orderNo : 暂无数据)</orderNo>
    

    尝试许久~发现这种表达式是不支持

    那么如果需要判断参数以返回不同内容 ,我们该怎么办呢?
    发现了这个扩展:wiremock-velocity-transformer,我看到它给的Demo中是这样写的:

    {
        "requestAbsoluteUrl" : "$requestAbsoluteUrl",
        "requestBody" : "$requestBody",
        "requestMethod" : "$requestMethod",
        "requestHeaderHost" : "$requestHeaderHost",
        "requestHeaderUserAgent" : "$requestHeaderUserAgent",
        "requestHeaderAcceptAccept" : "$requestHeaderAccept",
        "requestHeaderAcceptLanguage" : "$requestHeaderAcceptLanguage",
        "requestHeaderAcceptEncoding" : "$requestHeaderAcceptEncoding",
        "requestHeaderConnection" : "$requestHeaderConnection",
        "date" : "$date",
        "math": "$math.round(22.2)",
        #if($requestAbsoluteUrl == 'http://localhost:8089/my/resource')
        "customProp" : "customValue",
        "customProp2" : "customValue2",
        #else
        "customProp" : "customValue",
        #end
        "date" : "$date.getMonth()",
        "math" : "$math.floor(2.5)"
    }
    

    我发现了 #if()表达式,我需要这个~ 于是运行一下看看效果
    GitHub中它也提供了Standalone的运行方法,跟之前body-transformer类似,名称不一样而已~

    // 请注意你下载的这两个jar包的版本号和名称,不要盲目复制运行
    java -cp "wiremock-standalone-2.1.12.jar:wiremock-velocity-transformer-standalone-1.4.jar" com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --verbose --extensions com.github.adamyork.wiremock.transformer.VelocityResponseTransformer
    

    它提供的request 内容:

    {
        "request": {
            "urlPattern": "/resource",
            "method": "GET"
        },
        "response": {
            "status": 200,
            "bodyFileName": "response-test-body.vm",
            "headers": {
                "Content-Type": "application/json"
            }
        }
    }
    
    

    运行一下看看效果


    image.png

    可以看到他提供的 $requestBody #if() #date #math() 等等方法都是可以直接用的,非常不错。
    这里要注意, 这个扩展并不支持之前的$(xxx)这种格式, 因为$(xxx)这是body-transformer扩展中的方法。
    下面只要同时加载这两个扩展就能满足我的需求。

    官方文档 Standalone部分中这样说明

    --extensions: Extension class names e.g. 
    com.mycorp.HeaderTransformer,com.mycorp.BodyTransformer. See extending-wiremock.
    

    Transformer之间以“ , ”分割, 完美~

    还有之前设置 -port 的解释说明呦,有问题可以在这里找找~

    --port: Set the HTTP port number e.g. --port 9999
    

    最终,我们讲所用到的所有jar包(wiremock-standalone-2.3.1.jar ,wiremock-body-transformer-1.1.6.jar,wiremock-velocity-transformer-standalone-1.4.jar)
    放在同一目录下,运行~

    // 请注意你下载的jar包的版本号和名称,不要盲目复制运行
    java -cp "wiremock-standalone-2.3.1.jar:wiremock-body-transformer-1.1.6.jar:wiremock-velocity-transformer-standalone-1.4.jar" com.github.tomakehurst.wiremock.standalone.WireMockServerRunner --verbose --extensions com.github.adamyork.wiremock.transformer.VelocityResponseTransformer,com.opentable.extension.BodyTransformer  -port 7777
    

    测试一下效果~

    依然是先创建request,格式是json,文件名随意,内容如下:

    {
        "request": {
            "method": "POST",
            "urlPath": "/transform/post/double"
        },
        "response": {
            "status": 200,
            "bodyFileName": "response-doubel-body.vm",
            "headers": {
                "Content-Type": "text/xml"
            },
            "transformers": ["body-transformer"]
        }
    }
    
    
    

    在 __files 文件夹中创建 response-doubel-body.vm这个文件,内容如下:

    <?xmlversion='1.0'encoding='UTF-8'?>
    <node>
        <to>$(body.node.to)</to>
        <from>$(body.node.from)</from>
        <heading>
            <order>
                <orderNo>$(body.node.heading.order.orderNo)</orderNo>
                #if($requestBody.contains('from'))
                <orderNo2>$(body.node.heading.order.orderNo2)</orderNo2>
                #else
                <orderNo2>no from node</orderNo2>
                #end
            </order>
        </heading>
    </node>
    

    解释:
    这里用到了Java的contains方法,意思判断requestBody中是否包含'from'标签,从而显示不同的内容,在这里我就理解成from标签了,当然如果任意标签中存在"from"字符串也是可以匹配到的,由于扩展提供方法有限,只能这样意思下,暂时还不知道有什么方法可以完美的筛选标签或者内容, 这里不必要在意细节, 毕竟是测试嘛~
    运行下看看效果:更改mappings记得重启服务~

    有from标签
    无from标签

    没有问题~ , 至此功能需求基本满足,WireMock 的搭建和运行测试也已完结,这些功能应该可以满足大部分需求, 比较只是本地测试服务,小小的意思下就可以了。 好啦。 本文完结~ 有问题的小伙伴欢迎留言讨论~
    附上本文所用Demo

    相关文章

      网友评论

          本文标题:WireMock 搭建本地测试服务及使用案例

          本文链接:https://www.haomeiwen.com/subject/moemwxtx.html