美文网首页
OkHttp3IdlingResource

OkHttp3IdlingResource

作者: sylviaMo | 来源:发表于2017-11-24 15:21 被阅读77次

    简介

    OkHttp3IdlingResource是Jake Wharton大神为okhttp写的Espresso的IdlingResource,目前支持到OkHttp3.

    使用方法比较简洁:

    1、在test case 开始之前,注册根据OkHttpClient实例创建的IdlingResource

    OkHttpClient  client =//...
    
    IdlingResource resource = OkHttp3IdlingResource.create( "OkHttp", client);
    Espresso.registerIdlingResources(resource);
    

    2、在test case结束后,注销IdlingResource

    Espresso.unregisterIdlingResources(resource);
    

    源码可以参见:https://github.com/JakeWharton/okhttp-idling-resource

    剖析实现方式

    OkHttp3IdlingResource 首先是肯定要implementsIdlingResource,所以就有如下三个接口了:

    @Override
    
    public String getName() {
    return name;
    }
    
    @Override
    
    public boolean isIdleNow() {
    
    return dispatcher.runningCallsCount() == 0;
    }
    
    @Override
    
    public void registerIdleTransitionCallback(ResourceCallback callback) {
    this.callback = callback;
    }
    

    这三个接口的解释,请参考Espresso UI测试#IdlingResource

    从这三个接口,目前也没有发现很高深的内容,那大神是怎么实现的呢?

    我们要看上文使用方式里的create OkHttp3IdlingResource的方法了:

    
    @CheckResult
    @NonNull
    @SuppressWarnings("ConstantConditions") // Extra guards as a library.
    public static OkHttp3IdlingResource create(@NonNull String name, @NonNull OkHttpClient client) {
      if (name == null) throw new NullPointerException("name == null");
      if (client == null) throw new NullPointerException("client == null");
      return new OkHttp3IdlingResource(name, client.dispatcher());
    }
    

    1、name 和 client 是不可以为null,如果是null,就抛exception
    2、如果name 和 client都不是null,则创建OkHttp3IdlingResource

    private OkHttp3IdlingResource(String name, Dispatcher dispatcher) {
      this.name = name;
      this.dispatcher = dispatcher;
      dispatcher.setIdleCallback(new Runnable() {
          @Override
          public void run() {
            ResourceCallback callback = OkHttp3IdlingResource.this.callback;
            if (callback != null) {
              callback.onTransitionToIdle();
            }
          }
        });
    }
    

    1、当创建OkHttp3IdlingResource时,把HttpClient的dispatcher传递过来
    2、调用dispatcher.setIdleCallback()

    可是什么时候会触发这个Runnable内的run()函数呢?

    我们去看OkHttp的Dispatcher这个类,show you the code:

    private <T> void finished(Deque<T> calls, T call, boolean promoteCalls) {
        int runningCallsCount;
        Runnable idleCallback;
        synchronized(this) {
            if(!calls.remove(call)) {
                throw new AssertionError("Call wasn\'t in-flight!");
            }
     
            if(promoteCalls) {
                this.promoteCalls();
            }
     
            runningCallsCount = this.runningCallsCount();
            idleCallback = this.idleCallback;
        }
     
        if(runningCallsCount == 0 && idleCallback != null) {
            idleCallback.run();
        }
     
    }
    

    可以看到是当runningCallsCount 为0 的时候,会触发。

    正好结合官方文档里对setIdleCallback(Runnable idleCallback)这个函数的描述:

    Set a callback to be invoked each time the dispatcher becomes idle (when the number of running calls returns to zero).

    那么我们更肯定,当请求结束后,就是idle的状态了。

    所以当我们在写UI测试时,对于使用OkHttp 进行网络请求的页面,就可以在test case 开始之前注册OkHttp3IdlingResource,在test case 结束后注销OkHttp3IdlingResource,而不用自己单独去实现IdlingResource这个接口了。

    名词解释

    Dispatcher

    Policy on when async requests are executed.

    IdlingResource

    Represents a resource of an application under test which can cause asynchronous background work to happen during test execution (e.g. an intent service that processes a button click). By default, Espresso synchronizes all view operations with the UI thread as well as AsyncTasks; however, it has no way of doing so with "hand-made" resources. In such cases, test authors can register the custom resource and {@link Espresso} will wait for the resource to become idle prior to executing a view operation.

    相关文章

      网友评论

          本文标题:OkHttp3IdlingResource

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