WireMock 让你轻松模拟API 2022-06-13

哈喽,大家好,我是指北君。

我们开发过程中,前端和后端的开发大多时同时进行的,而前端开发需要访问某个接口返回数据的时,我们可以使用WireMock模拟指定API返回指定测试数据,这可以极大的方便我们的开发工作。今天就介绍如何使用WireMock搭建一个HTTP模拟器,并将一些基本案例。

1. 前言

WireMock 是一个Http 模拟服务,其核心也是一个web服务,WireMock主要是为特定请求提供固定的返回值。

WireMock可以作为单独进程启动,模拟一个WEB服务器,提供一些API访问,并返回特定的返回值。也可以作为第三方库在项目中使用。

下面我们先介绍以下WireMock模拟WEB服务器的使用吧。

2. WireMock搭建

  1. 第一步,先下载WireMock的Jar包, 本教程使用下载地址如下 : https://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-jre8-standalone/2.33.2/wiremock-jre8-standalone-2.33.2.jar

  2. 到指定目录启动Jar,同时也可以加一些启动参数。下面的命令表示用9998端口启动这个模拟服务器。

    1
    java -jar wiremock-jre8-standalone-2.33.2.jar -port 9998
    

    启动界面如下:

    image-20220611233259403

3. WireMock使用

WireMock启动时候,文件夹里面会有 _files 和 mappings 两个文件夹, _files文件夹中可以放一些返回数据文件。 mappings文件夹中存放映射关系,使用json格式的文件。

image-20220611234713740

如下图,新建json文件,启动WireMock时回加载这些文件,更新之后只需要重启WireMock即可。

image-20220611234749588

3.1 简单API映射

json文件如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
	"mappings": [
		{
			"request": {
				"method": "GET",
				"url": "/api/hello"
			},
			"response": {
				"body": "Hello world!",
				"headers": {
					"Content-Type": "text/plain"
				},
				"status": 200
			}
		}
	]
}

启动后正常访问:

image-20220611235614031

如果配置的地址访问不到也会返回错误,如下:

image-20220611235522950

3.2 返回response中添加header

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "request": {
        "method": "GET",
        "url": "/whatever"
    },
    "response": {
        "status": 200,
        "headers": {
            "Content-Type": "text/plain",
            "Set-Cookie": ["session_id=91837492837", "split_test_group=B"],
            "Cache-Control": "no-cache"
        }
    }
}

3.3 返回数组

1
2
3
4
5
6
    "response": {
        "status": 200,
        "jsonBody": {
          "arbitrary_json": [1, 2, 3]
        }
    }

3.4 返回指定文件数据 写在_file文件夹里面

1
2
3
4
5
6
7
8
9
10
{
    "request": {
        "method": "GET",
        "url": "/bodyfile"
    },
    "response": {
        "status": 200,
        "bodyFileName": "/myfile.xml"
    }
}

_file文件夹下面新建的文件:

image-20220612000607751

访问接口则可以直接返回文件中的数据:

image-20220612000758856

3.5 URL 映射

WireMock也支持映射正则表达式:

1
2
3
4
5
6
7
{
  "request": {
    "urlPattern": "/your/([a-z]*)\?and=query"
    ...
  },
  ...
}

3.6 指定请求头

1
2
3
4
5
6
7
8
9
10
11
12
13
{
  "request": {
    ...
    "headers": {
      "Content-Type": {
        "equalTo": "application/json",
        "caseInsensitive": true
      }
    }
    ...
  },
  ...
}

3.7 可变状态请求

requiredScenarioState/newScenarioState 可以记录当前API映射所处的状态以及新的状态,可以通过改变其状态,从而可以使同一个API返回不同的结果, 如下面的请求则可以改变状态,返回不同的结果.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
	"mappings": [
		{
			"scenarioName": "To do list",
			"requiredScenarioState": "Started",
			"request": {
				"method": "GET",
				"url": "/todo/items"
			},
			"response": {
				"status": 200,
				"body": "<items><item>Buy milk</item></items>"
			}
		},
		{
			"scenarioName": "To do list",
			"requiredScenarioState": "Started",
			"newScenarioState": "Cancel newspaper item added",
			"request": {
				"method": "POST",
				"url": "/todo/items",
				"bodyPatterns": [
					{
						"contains": "Cancel newspaper subscription"
					}
				]
			},
			"response": {
				"status": 201
			}
		},
		{
			"scenarioName": "To do list",
			"requiredScenarioState": "Cancel newspaper item added",
			"request": {
				"method": "GET",
				"url": "/todo/items"
			},
			"response": {
				"status": 200,
				"body": "<items><item>Buy milk</item><item>Cancel newspaper subscription</item></items>"
			}
		}
	]
}
  • 第一次访问时,Started状态:

    image-20220612095511082

  • 访问第二个接口,改变其状态如下

    image-20220612100007774

  • 再次访问API,返回新的数据

    image-20220612100120259

3.8 API 故障模拟

设置延时返回,如下可以设置定时延迟2秒。

1
2
3
4
5
6
7
8
9
10
	{
		"request": {
			"method": "GET",
			"url": "/delayed"
		},
		"response": {
			"status": 200,
			"fixedDelayMilliseconds": 2000
		}
	}

如下是延迟2秒的返回结果。

image-20220612101226438

同时也可以设置随机的延迟时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "request": {
        "method": "GET",
        "url": "/random/delayed"
    },
    "response": {
        "status": 200,
        "delayDistribution": {
            "type": "lognormal",
            "median": 50,
            "sigma": 0.4
    }
    }
}

总结

WireMock可以快速搭建Web服务,可以模拟开发测试需要的各种请求,使用十分方便。对于维护测试环境稳定以及提高开发效率方面都有不错的效果。

Java Geek Tech wechat
欢迎订阅 Java 技术指北,这里分享关于 Java 的一切。