美文网首页
OKhttp Mock 服务返回数据

OKhttp Mock 服务返回数据

作者: 技术客栈 | 来源:发表于2020-07-27 12:12 被阅读0次

    背景

    在我们经常开发的时候,通常我们都会把时间花费在接口联调和等待接口阶段。作为开发人员我应该自己做出单元测试,但是这并不是我今天要描述的范围,今天我只要是以在后台接口还没有开发完成的阶段,协调测试先给出数据的响应格式,从而开发人员自己Mock 数据。以此,开发接下的流程。的确,在前一两年我还是自己搭建Tomcat 然后在自己的本地服务器存放自己需要Mock 解析的Json 文件。以此达到这样的目的,但是这样是存在一个问题,那就是接口的入参,在此就需要作出校验,很显然我们对这样的方式,表示不认同。所以,有了以下的内容。

    简介

    由于项目的网络框架是使用的是Retrofit+RxJava从而在实现上,有很大的便利。需要注意的是Retrofit是对于Okhttp 的再优化和封装。看到Okhttp 有没有想到什么。对的他有很强大的功能那就是Interceptor(拦截器)。

    我们需要了解一下的几点:

    Interceptor

    OkHttp 可在 Request 和 Response 中设置任意个数的 Intercepor。对请求体和响应体进行处理。借助 OkHttp Interceptor 机制,创建一个 MockIntercepor,模拟返回一个 Response。当然他不只可以在Request、Response设置拦截,并且还可以设置网络状态的拦截、Header、等等。不在一一的赘述。如果你还不是足够的了解他的原理和使用方式,你可以观看一下的介绍https://github.com/square/okhttp/wiki/Interceptors

    1. HeaderInterceptor

    统一配置请求头,无需直接在业务封装层进行相关配置。减少代码的耦合性。

     /**
       * 设置请求Header
       *
       */
      public class HeaderInterceptor implements Interceptor {
          @Override
          public Response intercept(Chain chain) throws IOException {
              Request request = chain.request();
              Request.Builder builder = request.newBuilder();
              builder.addHeader("-Header", creatHeader())
                      .addHeader("user-agent", "公司名称/应用名称")
                      .build();
              Request newRequest = builder.build();
      
              return chain.proceed(newRequest);
          }
      
          /**
           * Request Header
           * <p> 由于sign 与 URL 关联因此,它可理解为动态的参数,而不能理解为固定参数</p>
           *
           * @return
           */
          public String creatHeader() {
              StringBuffer header = new StringBuffer();
              header.append("platform").append("=").append("android").append(";")
                      .append("os").append("=").append(Build.VERSION.SDK_INT).append(";")
                      .append("appid").append("=").append("com.xxx.xxx").append(";")
                      .append("version").append("=").append("2320").append(";")
                      .append("mid").append("=").append(Build.MODEL.replaceAll(" ", "_")).append(";")
                      .append("channel").append("=").append("ceshi");// 使用gradle 语法进行获取不同的渠道配置
              return header.toString();
          }
      
      }
    

    2. MockDataIntercepter

    在这里可能需要解释的是,因为我们在Mock 数据的时候,其实是直接跳过请求参数的配置,也就是说我们需要拦截Resphone 进行拦截。如果你使用了RxJava 操作符的类型转义,这时候你就需要在gradle 中配置在Debug 状态下不在配置RxJavaCallAdapterFactory。因为我只是在Debug状态下进行Mock 数据,所以在gradle 文件中配置变量,使其注入到BuildConfig 类型当中。已提供给项目全局使用,retrofitBuilder.addCallAdapterFactory(RxJavaCallAdapterFactory.create()); 具体配置如下:

    public class MockDataIntercepter implements Interceptor {
          private final String responeJsonPath;
      
          public MockDataIntercepter(String responeJsonPath) {
              this.responeJsonPath = responeJsonPath;
          }
          @Override
          public Response intercept(Chain chain) throws IOException {
              String responseString = createResponseBody(chain);
              //Response 配置
              Response response = new Response.Builder()
                      .code(200)
                      .message(responseString)
                      .request(chain.request())
                      .protocol(Protocol.HTTP_1_0)
                      .body(ResponseBody.create(MediaType.parse("application/json"), responseString.getBytes()))
                      .addHeader("content-type", "application/json")
                      .build();
              return response;
          }
      
      
          /**
           * 该方法是为动态的配置各个接口数据,为此,需要对各个接口的注解,进行
           * 拦截处理,以实现加载不同的json数据
           * @param chain
           * @return
           */
          private String createResponseBody(Chain chain) {
              String responseString = null;
              HttpUrl httpUrl = chain.request().url();
              String urlPath = httpUrl.url().toString();
      
              //url 匹配形式进行数据返回
       //      if (urlPath.matches("^(/users/)+[^/]+(/login)$")) {//匹配/users/{username}/login
      //            responseString = getResponseString("users_login.json");
      //        } else if (urlPath.matches("^(/users/)+[^/]*+$")) {//匹配/users/{username}
      //            responseString = getResponseString("test.json");
      //        }
              // 直接使用文件进行数据返回,不提倡。没有针对性
              return FileUtils.testCase;
          }
      
          private String getResponseString(String fileName) {
              return FileUtils.readFile(responeJsonPath +fileName,"UTF-8");
          }
      }
    

    当然使用这样的方式不仅能够实现这样两种的配置。我们进行网络的访问的时候通常会携带一些固定的参数,如version、os、platform 等,我们也可以针对固定参数的一些配置同样适用。再次就不在过多的赘述了。

    相关文章

      网友评论

          本文标题:OKhttp Mock 服务返回数据

          本文链接:https://www.haomeiwen.com/subject/egczlktx.html