android - 在 Espresso 中监控 Picasso 的 IdlingResource

标签 android picasso android-testing android-espresso

我希望能够让 EspressoPicasso 作为 IdlingResource 进行监控,以便我可以运行 ViewMatcher成功加载图像后,将出现 s。

通过浏览 Picasso 源代码,我不明白为什么这不起作用。这是我尝试过的:

Picasso picasso = new Picasso.Builder(context).build();
Field dispatcherField = Picasso.class.getDeclaredField("dispatcher");
dispatcherField.setAccessible(true);

try {
  Dispatcher dispatcher = (Dispatcher) dispatcherField.get(picasso);
  Espresso.registerLooperAsIdlingResource(dispatcher.dispatcherThread.getLooper());
} catch (NoSuchFieldException e) {
  throw new PicassoHasBeenRefactoredException();
} catch (Exception e) {
  e.printStackTrace();
}

onView(withId(R.id.image_view)).check(matches(withImage(R.drawable.drawable)));

(是的,我知道,反射很烦人,但我找不到另一种方法来获取Looper的句柄)

但是当尝试从 ImageView 获取 Bitmap 时,会导致此错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap android.graphics.drawable.BitmapDrawable.getBitmap()' on a null object reference

为了检查加载图像后测试是否按预期运行,我尝试引入 Thread.sleep(1000) 来代替 IdlingResource 检查并通过了。

是否可以安全地假设 IdlingResource 尚未正确设置,更重要的是,在使用 Espresso 检查 View 之前等待 Picasso 完成加载的正确方法是什么?

最佳答案

我正在使用 IdlingResource 来检查是否还有剩余操作。

请注意,IdlingResource 必须与 Picasso 位于同一包中才能访问受包保护的变量

package com.squareup.picasso;

public class PicassoIdlingResource implements IdlingResource, ActivityLifecycleCallback {
  protected ResourceCallback callback;

  WeakReference<Picasso> picassoWeakReference;

  @Override
  public String getName() {
    return "PicassoIdlingResource";
  }

  @Override
  public boolean isIdleNow() {
    if (isIdle()) {
      notifyDone();
      return true;
    } else {
      return false;
    }
  }

  public boolean isIdle() {
    return picassoWeakReference == null
            || picassoWeakReference.get() == null
            || picassoWeakReference.get().targetToAction.isEmpty();
  }

  @Override
  public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
    this.callback = resourceCallback;
  }

  void notifyDone() {
    if (callback != null) {
      callback.onTransitionToIdle();
    }
  }

  @Override
  public void onActivityLifecycleChanged(Activity activity, Stage stage) {
    switch (stage) {
      case CREATED:
        picassoWeakReference = new WeakReference<>(Picasso.with(activity));
        break;
      case STOPPED:
        // Clean up reference
        picassoWeakReference = null;
        break;
      default: // NOP
    }
  }
}

我认为不需要使用 Wea​​kReference,但它也没有坏处。

此外,我还发现了一种情况,它不会等到 Picasso 完成(使用 .load(null) 时)。因此,请自行承担使用风险,如果您改进了它,请回来。

有关完整详细信息和用法,请参阅要点 ( https://gist.github.com/Maragues/0c0db81a137c8d067396 )

关于android - 在 Espresso 中监控 Picasso 的 IdlingResource,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32779549/

相关文章:

android - 如何使图表适合android上的布局

Android 库 Picasso 还是 Glide?

android - Power Mockito 返回错误 org.powermock.api.mockito.ClassNotPreparedException

java - 在类中添加 Intent

android-fragments - 当我尝试从 Android 测试中的 fragmentManager 获取片段时,为什么会出现 NullPointerException?

android - 使用 anything() 时出错;在 Android 中测试不兼容的类型需要 : Matcher <View> found: Matcher <Object>

Android - 重启后打开系列 Activity

java - 从 Imageview 中的图像中获取特定颜色的所有像素

android - 在Android上切换USB音频

android - picasso 无法在 Android 中加载