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

入门

什么是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的图案:


WireMock 搭建本地测试服务及使用案例_第1张图片
启动成功图

这时候该文件目录下会出现两个文件夹
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": "$(body.node.to)$(body.node.from)$(body.node.heading.order.orderNo)$(body.node.heading.order.orderNo2)",
        "headers": {
            "Content-Type": "text/xml"
        },
        "transformers": ["body-transformer"]
    }
}

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

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

WireMock 搭建本地测试服务及使用案例_第2张图片
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中的内容:


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

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

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

进阶二

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

$(body.orderNo > 0 ? body.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"
        }
    }
}

运行一下看看效果


WireMock 搭建本地测试服务及使用案例_第3张图片
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这个文件,内容如下:



    $(body.node.to)
    $(body.node.from)
    
        
            $(body.node.heading.order.orderNo)
            #if($requestBody.contains('from'))
            $(body.node.heading.order.orderNo2)
            #else
            no from node
            #end
        
    

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

WireMock 搭建本地测试服务及使用案例_第4张图片
有from标签

WireMock 搭建本地测试服务及使用案例_第5张图片
无from标签

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

你可能感兴趣的:(WireMock 搭建本地测试服务及使用案例)