2015-09-25 82 views
1

我希望能够将Espresso监视器Picasso作为IdlingResource,以便我可以在图像加载成功后运行ViewMatcher监测浓缩咖啡中IdlingResource的毕加索

从浏览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 

要检查预期一旦图像已加载测试运行,我想代替IdlingResource检查的的引入Thread.sleep(1000)它通过了。

可以肯定IdlingResource设置不正确,更重要的是,在检查Espresso视图之前等待Picasso完成加载的正确方法是什么?

+0

不能使用[onSucess回调(https://square.github.io/picasso/javadoc/com/squareup/picasso/Callback.html #onSuccess--)从毕加索设置您的IdelingResource? –

+0

@RahulTiwari我不想修改任何生产代码来适应测试,除非你的意思是别的吗? –

+0

我在谈论使用回调毕加索提供'onSuccess'和'onError'并尽可能地去除反射。所以是的,我在谈论修改代码,但它不会影响任何功能。 –

回答

2

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

注意,IdlingResource必须住在同一个包毕加索来访问一个包保护变量

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 
    } 
    } 
} 

我不认为使用WeakReference的是需要的,但它也没有破坏。

此外,我已经确定了一个案例,它不会等到毕加索结束(使用.load(null))。所以,请自担风险,如果您改进,请回来。

见的全部细节和使用要点(https://gist.github.com/Maragues/0c0db81a137c8d067396

+0

谢谢!在活动之间移动时,解决方案无法正常工作。为了解决这个问题,我用** RESUMED&PAUSED **取代了状态CREATED&STOPPED ** –

+0

我还发现这导致了大的延迟(每个图像加载**导致**延迟5秒),因为Espresso在重新启动之间有几秒钟的延迟,检查。解决方法是强制重新检查PicassoIdlingResource,如下例所示:https://gist.github.com/vaughandroid/e2fda716c7cf6853fa79#file-viewvisibilityidlingresource-java-L62 –

+0

谢谢@SebasLG,我目前正在另一个项目中,一旦我回到旧的代码,就会检查你的代码。 – Maragues