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

a5b672a6da3cb28b539799b6dbac43d7.png

启动成功图

这时候该文件目录下会出现两个文件夹

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 别忘了端口号呦~

4cf8a53506b725837e5b2bff6f84af22.png

该错误是正常的,因为我们返回的是内容是two.json的文件,可是我们并没有写这个文件,下面我们只要在__files中创建这个json文件即可

{ "equalToJson" : "{ "name": "new product", "creator": "tester", "createTime": "2015-09-07" }", "jsonCompareMode": "LENIENT" }

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

6c96afca6d952b8b3ab8724ef5779413.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请求中的参数名称,用$()包裹,保存后重启服务,在浏览器中打开

e89c58b3318bf119e43b4dc5b572ba79.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格式,来看下效果

c20bd180f667a0db4b5d69b9eb29fe1c.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" } } }

运行一下看看效果

9c894dcb3a0fa18370497f6113e46a72.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'?> $(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记得重启服务~

61e7dee7457fa52976a2774d9f75956a.png

有from标签

dc1aa55afa34ffdf8bcc32332beb6def.png

无from标签

没有问题~ , 至此功能需求基本满足,WireMock 的搭建和运行测试也已完结,这些功能应该可以满足大部分需求

Logo

前往低代码交流专区

更多推荐