在工程中使用WireMock库

自己一直用wiremock的standalone版本,代码中使用的时候就简单封装了http请求来使用,后来看了一下wiremock自己的client使用起来也不错,也支持远端访问,于是推荐给大家

使用本地wiremock

一个stub的demo

  1. 首先在pom中加好dependency
<dependency>
    <groupId>com.github.tomakehurst</groupId>
    <artifactId>wiremock</artifactId>
    <version>1.56</version>

    <!-- Include everything below here if you have dependency conflicts -->
    <classifier>standalone</classifier>
    <exclusions>
        <exclusion>
          <groupId>org.mortbay.jetty</groupId>
          <artifactId>jetty</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.apache.httpcomponents</groupId>
          <artifactId>httpclient</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.skyscreamer</groupId>
          <artifactId>jsonassert</artifactId>
        </exclusion>
        <exclusion>
          <groupId>xmlunit</groupId>
          <artifactId>xmlunit</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.jayway.jsonpath</groupId>
          <artifactId>json-path</artifactId>
        </exclusion>
        <exclusion>
          <groupId>net.sf.jopt-simple</groupId>
          <artifactId>jopt-simple</artifactId>
        </exclusion>
     </exclusions>
</dependency>
  1. 在java文件中需要导入wiremocker的server、client、config这三个类
import com.github.tomakehurst.wiremock.WireMockServer;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
  1. 然后这里是testNg的demo
 1     @BeforeClass
 2     public void setUp() throws FileNotFoundException, IOException
 3     {
 4     //配置本地端口
 5         WireMock.configureFor(9090);
 6         wireMockServer = new WireMockServer(wireMockConfig().port(9090)); 
 7         log.info("START WIREMOCK");
 8     //启动
 9         wireMockServer.start();
10     }
11 
12     @AfterClass
13     public void tearDown() throws FileNotFoundException, IOException
14     {
15     //停掉mock
16         wireMockServer.stop();
17     }
18 
19 
20     @Test
21     public void testForMock()
22     {
23 
24         //配置rule
25         stubFor(post(urlEqualTo("/api/add"))
26                     .willReturn(aResponse().withStatus(200).withBody("hzmali")));
27         //自己写的post方法
28         String response=HttpUtil.post("http://127.0.0.1:9090/api/add","");
29         log.info("GET RESP:"+response);
30         //检查
31         Assert.assertTrue(response.contains("hzmali"));
32 
33 
34         }
35 }

结果成功,日志正常

[INFO ]11:52:54, [Class]MockCliTest, [Method]setUp, START WIREMOCK
[INFO ]11:52:54, [Class]MockCliTest, [Method]testForMock, GET RESP:hzmali
PASSED: testForMock

这里的rule设置

        stubFor(post(urlEqualTo("/api/add"))
                    .willReturn(aResponse().withStatus(200).withBody("hzmali")));

等效于通常的json配置

"requestt" : {
    "url" : "/api/add",
    "method" : "POST"
  },
    "response" : {
    "status" : 200,
    "body" : "hzmali"
  }

更多高级stub规则如:
URL的正则匹配:

stubFor(put(urlMatching("/thing/matching/[0-9]+"))
    .willReturn(aResponse().withStatus(200)));

stubFor(put(urlMatching("/thing/matching/.*"))
    .willReturn(aResponse().withStatus(200)));

REQUEST的header和body的匹配

stubFor(post(urlEqualTo("/with/headers"))
    .withHeader("Content-Type", equalTo("text/xml"))
    .withHeader("Accept", matching("text/.*"))
    .withHeader("etag", notMatching("abcd.*"))
    .withHeader("X-Custom-Header", containing("2134"))
        .willReturn(aResponse().withStatus(200)));

stubFor(post(urlEqualTo("/with/json/body"))
    .withRequestBody(equalToJson("{ "houseNumber": 4, "postcode": "N1 1ZZ" }"))
    .willReturn(aResponse().withStatus(200)));

更多的stub匹配参数,指定返回文件等查看官方手册stub

访问远端wiremock

单元测试一般就像上述的那样起一个本地的wiremock去进行mock,接口测试时的wiremock一般建在另外机器上,所以在自动化接口测试时,跟本地调用有所区别

在上面demo的基础上进行修改,只需要告诉client这个mock在哪

WireMock.configureFor(“192.168.231.131”, 8080);

不需要去创建本地的wiremock,发送请求的地址当然也要改成和目的wiremock一致

 1     @BeforeClass
 2     public void setUp() throws FileNotFoundException, IOException
 3     {
 4         WireMock.configureFor("192.168.231.131", 8080);
 5         //wireMockServer = new WireMockServer(wireMockConfig()); 
 6         //log.info("START WIREMOCK");
 7         //wireMockServer.start();
 8     }
 9 
10     @AfterClass
11     public void tearDown() throws FileNotFoundException, IOException
12     {
13         //wireMockServer.stop();
14     }

wiremock日志中也看出是有设置rule并匹配上了

2015-07-11 12:39:06.438 Received request to /mappings/new with body {
  "request" : {
    "url" : "/api/add",
    "method" : "POST"
  },
  "response" : {
    "status" : 200,
    "body" : "hzmali"
  }
}
2015-07-11 12:39:06.519 Received request: POST /api/add HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0.1
Host: 192.168.231.131:8080
Content-Length: 0


2015-07-11 12:39:06.519 Request received:
POST /api/add HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0.1
Host: 192.168.231.131:8080
Content-Length: 0

后记

最新的wiremock官方主页上很良心的推荐了一些同类mock工具

Betamax
REST-driver
MockServer
Moco

  • Betamax:得配合Junit使用,注解的风格,无standalone版本无爱,页面太花哨看了一会就关了

  • REST-driver:主要用来测试restful 客户端和服务,所以分为client-driver,server-driver,主要用于单测
    ,其中server-driver封装了restful的请求和响应,拿来做接口测试的请求发送工具也很适合

  • Moco:一个可以轻松搭建测试服务器的框架/工具/程序库,支持socket,国人写的,语法和命令都很简洁

  • MockServer:功能比wiremock强大一圈,支持的功能和调用方式这些工具中最多的,支持maven、java api、standalone、node.js、docker镜像等方式的使用。
    其中比较特色的功能如下:

MockServer will play expectations in the exact order they are setup. For example, if an expectation A is setup to response (or forward) 3 times then expectation B is setup to response (or forward) 2 times for the same request MockServer will response (or forward) in the following order A, A, A, B, B.

感受了一下,对于某些场景(比如某个内部逻辑是需要触发失败重试或重连),需要第一次调用A接口返回异常,第二次调用A接口返回正常,对于调用方来说因内部调用接口的情况对外是不可见的,一般让第一次返回失败是很easy的,但没有什么好办法控制什么时候让第二次返回异常,那么MockServer这个按时序返回就很屌炸天了,有空研究一下

 
原文地址:https://www.cnblogs.com/opama/p/4638535.html