What?什么是 Mock Server
Mock 是模拟的意思。在测试中,通常表述为:对测试过程中不容易构造或者不容易获取的物件,用一个虚拟的物件来进行模拟的一个过程。能够提供 Mock 功能的服务就叫作 Mock Server。 Mock Server 通过模拟真实的服务,提供对来自客户端请求的真实响应。
Why?为什么要用 Mock Server
- 在开发初期先模拟外部接口,避免直接使用实际外部接口进行开发调试,提高开发效率
- 全面准确的模拟外部接口的返回,提高自身代码的可靠性,提升验证的全面性
How?怎么用 Mock Server
主要包括两种使用方式,一种是通过一个现成的 Mock Server 服务,这种的好处是对代码无侵入,只需要将调用的 URL 修改为 Mock Server 提供的 URL 即可。另一种是在代码里面显式的编写相关的规则,这样的好处是不再需要单独启用服务,在代码里面就可以完成 Mock,主要在单测的时候使用。
使用方式一:通过现成的服务打桩
可以使用类似 apifox 工具本地/线上打桩,apifox 不仅有基于 Swgger 的 API 管理的能力,同时也具备 API Mock 的功能。具体使用方法可以访问: https://www.apifox.cn/
使用方式二:通过代码打桩
MockServer 官方文档 http://www.mock-server.com Maven 引入
<dependency><groupId>org.mock-server</groupId><artifactId>mockserver-netty</artifactId><version>5.4.1</version>
</dependency>
<dependency><groupId>org.mock-server</groupId><artifactId>mockserver-client-java</artifactId><version>5.4.1</version>
</dependency>
示例一
ClientAndServer 用法
package com.yzy.mock;import org.mockserver.integration.ClientAndServer;
import org.mockserver.model.Cookie;import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
import static org.mockserver.model.Parameter.param;public class MockServer {public static void main(String[] args) {ClientAndServer server = new ClientAndServer(1080);server.when(request().withMethod("GET").withPath("/test").withQueryStringParameters(param("p", "1"))).respond(response().withCookie(new Cookie("cKey", "cValue")).withBody("test1"));server.when(request().withMethod("GET").withPath("/test").withQueryStringParameters(param("p", "2"))).respond(response().withBody("test2"));}
}
启动 main 方法,打开浏览器,输入 http://localhost:1080/test?p=1,页面返回test1,并且成功写入cookie。注意写入的cookie 是Session 级别的,会话关闭将消失。输入http://localhost:1080/test?p=2,页面返回 test2,说明 MockServer 同时监听的两个匹配都有效。
示例二
MockServerClient 用法
package mock;import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.junit.Rule;
import org.junit.Test;
import org.mockserver.client.MockServerClient;
import org.mockserver.junit.MockServerRule;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;public class MockServerTest {@Rulepublic MockServerRule server = new MockServerRule(this, 1080);@Testpublic void test() throws IOException {MockServerClient mockClient = new MockServerClient("localhost", 1080);String expected = "hello world";mockClient.when(request().withPath("/hello").withMethod("GET")).respond(response().withStatusCode(200).withBody(expected));CloseableHttpClient client = HttpClients.createDefault();HttpGet httpGet = new HttpGet("http://localhost:1080/hello");CloseableHttpResponse response = client.execute(httpGet);//验证InputStream content = response.getEntity().getContent();InputStreamReader inputStreamReader = new InputStreamReader(content);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String responseText = bufferedReader.readLine();assertThat(responseText, equalTo(expected));}
}