1、Mock Server的简介
MockServer可用于模拟通过HTTP或HTTPS(即服务,网站等)集成系统。
具体到模拟服务上,处理的手法也是各种各样,因为服务以HTTP集成居多,无论是Web Service,还是REST,所以,一种典型的做法是,开发一个模拟服务,打成WAR包,部署到一个应用服务器上。而我们知道,一旦牵扯到应用服务器部署,就是非常耗时的,部署的时间量级通常是分钟级的。而且,模拟服务器通常不是一次性的工作,我们需要在开发过程中,反复调整,这就进一步增加了维护一个模拟服务器的成本。有的应用服务器是非常消耗资源的,要用专门的机器来部署它。更进一步,如果机器资源有限,团队就只能共享一台机器,这样,即便我为测试自己的部分做一个小的改动,很有可能因为得不到机器的使用权,而要等上几天时间。
Moco就是针对这样一个特定的场景而生的。Moco是一个简单搭建模拟服务器的程序库/工具,这个基于 Java 开发的开源项目已经在 Github 上获得了不少的关注。该项目的简介是这样描述自己的:Moco 是一个简单搭建 stub 的框架,主要用于测试和集成。
Moco本身支持API和独立运行两种方式。通过使用API,开发人员可以在JUnit、JBehave等测试测试框架里使用Moco,极大程度地降低了集成点测试的复杂度
Moco可以提供以下服务:
- HTTP APIs
- Socket APIs
- REST API
Moco原理简介:Moco会根据一些配置,启动一个真正的HTTP服务(会监听本地的某个端口)。当发起请求满足一个条件时,它就给回复一个应答。Moco的底层没有依赖于像Servlet这样的重型框架,而是基于一个叫Netty网络应用框架直接编写的,这样一来,绕过了复杂的应用服务器,所以,它的速度是极快的。
其实moco也算是一个挡板的作用,无法模拟具体的业务,只能做一个参数化的配置来时先模拟出一个http接口。
2、使用独立运行的方式来运行一个http服务
Moco独立运行时所需准备的有:
- Java运行环境
- moco-runner-0.11.0-standalone.jar
- moco下载地址: https://pan.baidu.com/s/1n4p_wl2wNZWZ_MmRXmB93A 提取码:7suo
3、如何运行moco
Moco的运行非常简单,只需要一行命令即可
如在命令行中运行:java -jar <path-to-moco-runner> http -p <monitor-port> -c < configuration -file>
<path-to-moco-runner>
:moco-runner-0.11.0-standalone.jar包的路径<monitor-port>
:http服务监听的端口<configuration -file>
:配置文件路径
很明显这个东西是springboot开发的并且还是热部署,你直接修改配置文件的内容他是可以立马生效的。
-
模拟get请求接口
配置文件如下test.json:
[
{
"request":
{
"uri" : "/workflowInterface/k2/Load.aspx",
"queries" : {
"BSID" : "SOC",
"BOID" : "123456",
"ProcID" : "hello"
},
"method" : "get"
},
"response" :
{
"text" : "Hello, Moco"
}
}
]
参数解析:
- uri : 约定接口的uri
- queries : 约定接口的请求参数 BSID必须等于SOC ,BOID必须等于123456,ProcID必须等于hello才可访问
- method: 约定请求的方式 get/post
- response:返还结果
java -jar moco-runner-0.11.1-standalone.jar http -p 12345 -c test.json
使用浏览器访问:
http://localhost:12345/workflowInterface/k2/Load.aspx?BSID=SOC&BOID=123456&ProcID=hello
使用java代码访问:
BufferedReader reader = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
try {
String url = "http://localhost:12345/workflowInterface/k2/Load.aspx?BSID=SOC&BOID=123456&ProcID=hello"
URL localURL = new URL(url);
URLConnection connection = localURL.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setRequestProperty("content-type", "application/json");
httpURLConnection.setConnectTimeout(5*1000);//设置连接时间为5秒
httpURLConnection.setReadTimeout(5*1000);//设置读取时间为5秒
//httpURLConnection.setInstanceFollowRedirects(false); // 必须设置false,否则会自动redirect到重定向后的地址
httpURLConnection.connect();
StringBuffer resultBuffer = new StringBuffer();
String tempLine = null;
// 得到响应码
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
// 得到响应流
inputStream = connection.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
reader = new BufferedReader(inputStreamReader);
while ((tempLine = reader.readLine()) != null) {
resultBuffer.append(tempLine);
}
//处理返还结果
System.err.println(resultBuffer.toString());
}
} catch (Exception e) {
flag=false;
logger.error("调用失败: ",e);
} finally {
if (reader != null) {
reader.close();
}
if (inputStreamReader != null) {
inputStreamReader.close();
}
if (inputStream != null) {
inputStream.close();
}
}
-
模拟post请求接口
配置文件foo.json如下
[
{
"request":
{
"uri" : "/test/webservice/dispatchPwd/getHostPassword",
"json":{"token":"123456","ipAddr":"192.168.19.110","account":"hello"},
"method" : "post"
},
"response" :
{
"json": {
"code" : "2000",
"data":"1017B897C5CF7A90BE7CB5DE8A1D0A26:56F7A1F60D5D8E93BAC74454D0A55FE0"
}
}
}
]
发布服务:
java -jar moco-runner-0.11.1-standalone.jar http -p 12345 -c foo.json
这个就无法直接使用浏览器进行访问了,得使用postman这类工具进行测试.
使用java代码调用:
/**
*
* @Title: httpPost
* @Description: 发送http Post请求
* @param url 请求路径
* @param params 请求参数map
* @return String
* @date 2019年10月18日下午4:05:47
*/
private String httpPost(String url, Map<String, String> params) {
HttpClient client = new DefaultHttpClient();
HttpResponse response = null;
String retMsg = "";
try {
HttpPost httpPost = new HttpPost(url);
String param = JSONObject.fromObject(params).toString();
StringEntity s = new StringEntity(param);
s.setContentEncoding("UTF-8");
s.setContentType("application/json");// 发送json数据需要设置contentType
httpPost.setEntity(s);
response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
//System.out.println("返回的结果:" + code);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//HttpEntity entity = response.getEntity();
retMsg = EntityUtils.toString(response.getEntity());// 返回json格式:
//System.out.println(retMsg);
logger.info("调用接口成功CODE:"+ code+"返还结果参数是:"+retMsg);
}else{
logger.error("调用接口失败CODE:"+ code);
return retMsg;
}
} catch (Exception e) {
logger.error("调用异常", e);
e.printStackTrace();
} finally {
try {
client.getConnectionManager().shutdown();
} catch (Exception e) {
logger.error("关闭client资源异常", e);
e.printStackTrace();
}
}
return retMsg;
}
模拟配置的接口完成