mock测试:moco模拟接口并使用HttpClient验证

1 mock测试

mock 的意思是模拟,模拟出一个我们预期的对象。这个对象我们一般指接口,当一个接口还不存在时,可以利用工具来把它模拟出来,这个接口与真实的接口拥有一样的入参和出参。但需要注意的是,mock的接口没有内部逻辑。

mock测试一般的使用情况:

  1. 前后端分离开发过程中,前端开发完成但后端未开发完成接口未提供,可以通过mock来模拟接口辅助前后端代码联调。
  2. 后端开发过程中,A接口依赖于B接口,但B接口由于外因还未开发完成,此时可以通过mock B接口来提供服务。
  3. 接口自动化脚本编写时,可以mock出还未开发完成的接口,等到接口开发完成,替换接口地址即可,节省了不必要的时间成本。

2 moco框架

moco框架是github上的一个开源项目,可模拟http,https,Socket协议。
moco的使用很简单。这里简单介绍一下。

2.1 下载jar包

http://central.maven.org/maven2/com/github/dreamhead/moco-runner/0.12.0/moco-runner-0.12.0-standalone.jar
这里选用的是0.12.0的版本

2.2 编写demo配置文件

[
  {
    "description": "第一个mock例子",
    "request":{
      "uri": "/demo"
    },
    "response" :
    {
      "text" : "Hello, Moco"
    }
  }
]

2.3 启动服务

java -jar moco-runner-0.12.0-standalone.jar http -p 8888 -c demo.json

进入浏览器验证
在这里插入图片描述

3 mock常见类型接口并验证

这里选择了几种常见的接口进行mock,并使用testNG+HttpClient进行验证。
testNG 和 HttpClient的版本:

<dependency>
    <groupId>org.testng</groupId>
    <artifactId>testng</artifactId>
    <version>6.14.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.9</version>
</dependency>

对于一些公共的配置,放在了 带有BeforeClass注解的 initialize函数中

public class MyHttpClient {
    private String url;
    private ResourceBundle bundle;
    //创建cookie store的本地实例
    private CookieStore cookieStore;
    //配置连接信息 RequestTimeout(连接池获取到连接的超时时间)、ConnectTimeout(建立连接的超时)、SocketTimeout(获取数据的超时时间)
    private RequestConfig requestConfig;
    //httpclient 上下文
    private HttpClientContext context = HttpClientContext.create();
    //header
    private List<Header> headerList;

    @BeforeClass
    public void initialize(){
        bundle = ResourceBundle.getBundle("httpclient",Locale.CHINA);
        this.url = bundle.getString("test.url");
        //创建cookie store的本地实例
        this.cookieStore = new BasicCookieStore();
        this.context.setCookieStore(cookieStore);
        //配置连接信息 RequestTimeout(连接池获取到连接的超时时间)、ConnectTimeout(建立连接的超时)、SocketTimeout(获取数据的超时时间)
        this.requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).setConnectionRequestTimeout(2000).build();
        //设置header
        this.headerList = new ArrayList<Header>();
        headerList.add(new BasicHeader("Content-Type","application/json"));
        headerList.add(new BasicHeader("User-Agent","Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"));
    }
 }

3.1 带cookie的get请求

json配置文件

[
  {
    "description": "get请求返回cookies",
    "request": {
      "uri": "/returnCookies",
      "method": "get"
    },
    "response":{
      "cookies": {
        "login": "true"
      },
      "json":{
        "des": "获取cookies"
      }
    }
  },
  {
    "description": "模拟带cookies get请求",
    "request":{
      "uri": "/getWithCookies",
      "method": "get",
      "cookies": {
        "login": "true"
      }
    },
    "response" :
    {
      "text" : "带cookies才能访问"
    }
  }
]

上面的模拟接口返回cookie信息,下面的接口需要携带上面接口返回的cookie才能访问。
接口验证

@Test
public void getRequest() throws IOException {
    String result;
    HttpGet get = new HttpGet(this.url + "/returnCookies");
    HttpClient client = HttpClients.custom().setDefaultRequestConfig(this.requestConfig).setDefaultCookieStore(this.cookieStore).setDefaultHeaders(this.headerList).build();
    HttpResponse response = client.execute(get,this.context);
    Assert.assertEquals(response.getStatusLine().getStatusCode(),200);
    result = EntityUtils.toString(response.getEntity(),"utf-8");
    //字符长转json
    JSONObject jsonResult = JSONObject.parseObject(result);
    System.out.println(jsonResult);

    //获取cookies信息
    for(Cookie c : this.cookieStore.getCookies()){
        System.out.println(c.getName() + "-----" + c.getValue());
    }
    ((CloseableHttpClient) client).close();
}

@Test(dependsOnMethods = "getRequest")
public void getWithCookies() throws IOException {
    String result;
    HttpGet get = new HttpGet(this.url + "/getWithCookies");
    HttpClient client = HttpClients.custom().setDefaultRequestConfig(this.requestConfig).setDefaultCookieStore(this.cookieStore).build();

    HttpResponse response = client.execute(get);
    Assert.assertEquals(response.getStatusLine().getStatusCode(),200);
    result = EntityUtils.toString(response.getEntity(),"utf-8");
    //字符长转json
    //JSONObject jsonResult = JSONObject.parseObject(result);
    System.out.println(result);
    ((CloseableHttpClient) client).close();
}

3.2 带参数的get请求

json配置文件

[
 {
  "description": "模拟带参数get请求",
  "request":{
    "uri": "/getParameter",
    "method": "get",
    "headers": {
  	  "Content-Type": "application/json"
	},
    "queries": {
      "name":"张山峰",
      "age": "18"
    }
  },
  "response" :
  {
    "text" : "有参数get请求"
  }
 }
]

接口验证:

@Test
@Parameters({"name","age"})
public void getParameter(String name,String age) throws URISyntaxException, IOException {
    String result;
    //get方法添加参数
    List<NameValuePair> params=new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("name",name));
    params.add(new BasicNameValuePair("age",age));
    URI uri = new URIBuilder(this.url + "/getParameter").setParameters(params).build();
    HttpGet get = new HttpGet(uri);
    HttpClient client = HttpClients.custom().setDefaultRequestConfig(this.requestConfig).setDefaultHeaders(headerList).build();
    HttpResponse response = client.execute(get);
    Assert.assertEquals(response.getStatusLine().getStatusCode(),200);
    result = EntityUtils.toString(response.getEntity(),"utf-8");
    System.out.println(result);
    ((CloseableHttpClient) client).close();
}

3.3 post请求表单提交

json配置文件

[
 {
  "description": "模拟带参数post请求,表单格式提交",
  "request":{
    "uri": "/postParamForm",
    "method": "post",
    "forms":{
      "name": "abc",
      "age": "22"
    }
  },
  "response" :
  {
    "json" : {
      "name": "ha"
    }
  }
 }
]

接口验证:

@Test
public void postFormRequest() throws IOException {
    HttpPost post = new HttpPost(this.url + "/postParamForm");
    //设置post参数
    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
    parameters.add(new BasicNameValuePair("name","abc"));
    parameters.add(new BasicNameValuePair("age","22"));
    //构造表单实体
    UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters);
    post.setEntity(formEntity);
    HttpClient client = HttpClients.custom().setDefaultRequestConfig(this.requestConfig).build();
    HttpResponse response = client.execute(post);
    Assert.assertEquals(response.getStatusLine().getStatusCode(),200);
    String result = EntityUtils.toString(response.getEntity(), "utf-8");
    //字符长转json
    JSONObject jsonResult = JSONObject.parseObject(result);
    System.out.println(jsonResult);
}

3.4 post请求json格式提交

json配置文件

[
 {
  "description": "模拟带参数post请求,json格式提交",
  "request":{
    "uri": "/postParamJson",
    "method": "post",
    "json":{
      "name": "abc",
      "age": 22
    }
  },
  "response" :
  {
    "json" : {
      "name": "ha"
    }
  }
 }
]

接口验证:

@Test
public void postJsonRequest() throws IOException {
    HttpPost post = new HttpPost(this.url + "/postParamJson");
    //json 格式参数
    JSONObject jsonParam = new JSONObject();
    jsonParam.put("name","abc");
    jsonParam.put("age",22);
    StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
    entity.setContentType("application/json");
    entity.setContentEncoding("UTF-8");
    post.setEntity(entity);
    HttpClient client = HttpClients.custom().setDefaultRequestConfig(this.requestConfig).build();
    HttpResponse response = client.execute(post);
    Assert.assertEquals(response.getStatusLine().getStatusCode(),200);
    String result = EntityUtils.toString(response.getEntity(), "utf-8");
    //字符长转json
    JSONObject jsonResult = JSONObject.parseObject(result);
    System.out.println(jsonResult);
    Reporter.log(result);
}

3.5 测试结果

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值