WireMock 伪造REST服务

交代背景

在工作的过程中,前后端工程师一般都是并行工作的,假如移动端工程师(Android ,ios)、Web工程师(公司主站)需要我后端的一个接口,或者需要知道后端会返回怎样的数据格式时,此时后端可能还在撸逻辑,或者说还在不停的修改逻辑或者重构代码,这个时候就比较尴尬啦!你可能会觉得他们自己就可以模拟相关HTTP接口,REST服务等…

引发问题

但是这样做,会有点问题,就是他们每个人都需要模拟这部分代码,并且可能每个人的理解都不相同,并且每个人做出的接口响应格式和传输格式,与后端设计出现的又有部分出路。

  1. 增加前端,移动端工程师的工作量
  2. 因为可能的理解偏差或者个人风格不同,设计出来的接口和后端的接口又不相同,增加继续沟通成本
  3. 假如项目需要重构或者修改部分逻辑,导致前段后端又需要重新设计

归根到底,解决这些问题最核心的原因就是后端控制;可以先设计REST服务(模拟服务),共前端,移动端开发者调用,后端也可以继续围绕着设计出的模拟服务去实现,一举两得。

WireMock 登场

WireMock网站

downloaded the standalone JAR

启动服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
➜  ~ cd ~/wiremock
➜ wiremock ll
total 24656
-rw-r--r--@ 1 niuhesm staff 12M Nov 4 19:05 wiremock-standalone-2.19.0.jar
➜ wiremock java -jar wiremock-standalone-2.19.0.jar --port 9999
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
/$$ /$$ /$$ /$$ /$$ /$$
| $$ /$ | $$|__/ | $$$ /$$$ | $$
| $$ /$$$| $$ /$$ /$$$$$$ /$$$$$$ | $$$$ /$$$$ /$$$$$$ /$$$$$$$| $$ /$$
| $$/$$ $$ $$| $$ /$$__ $$ /$$__ $$| $$ $$/$$ $$ /$$__ $$ /$$_____/| $$ /$$/
| $$$$_ $$$$| $$| $$ \__/| $$$$$$$$| $$ $$$| $$| $$ \ $$| $$ | $$$$$$/
| $$$/ \ $$$| $$| $$ | $$_____/| $$\ $ | $$| $$ | $$| $$ | $$_ $$
| $$/ \ $$| $$| $$ | $$$$$$$| $$ \/ | $$| $$$$$$/| $$$$$$$| $$ \ $$
|__/ \__/|__/|__/ \_______/|__/ |__/ \______/ \_______/|__/ \__/

port: 9999
enable-browser-proxying: false
disable-banner: false
no-request-journal: false
verbose: false

编写MockServer代码

Maven 配置
1
2
3
4
5
6
7
8
<!-- https://mvnrepository.com/artifact/com.github.tomakehurst/wiremock -->
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>2.19.0</version>
<type>pom</type>
<scope>test</scope>
</dependency>
核心代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MockServer {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
configureFor(8062);
removeAllMappings();

mock("/order/1", "01");
mock("/order/2", "02");
}

private static void mock(String url, String file) throws IOException {
ClassPathResource resource = new ClassPathResource("mock/response/" + file + ".txt");
String content = StringUtils.join(FileUtils.readLines(resource.getFile(), "UTF-8").toArray(), "\n");
stubFor(get(urlPathEqualTo(url)).willReturn(aResponse().withBody(content).withStatus(200)));
}

}
响应格式列表
1
2
3
4
{
"id":1,
"type":"C"
}
1
2
3
4
{
"id":2,
"type":"B"
}