android - Espresso + picasso + 勺子

标签 android unit-testing mocking picasso android-espresso

Picasso 使用线程在后台加载图像。即使从 Assets 加载时,在它出现之前也会有轻微的延迟,这会导致图片不会出现在用勺子捕获的图片上。我可以在测试中添加 1s sleep ,但我想知道是否有更好的方法。

我试图设置一个 Downloader 或一个 RequestHandler 来同步返回图像,但我想我需要设置一个 ExecutorService 来使用主线程或 AsyncTask(这样 espresso 就会等待)。通过改造,我们可以将 AsyncTask.THREAD_POOL_EXECUTORMainThreadExecutor 一起使用,但我不确定如何为 picasso 执行此操作。

作为解决方法,我将 picasso 包装在一个 ImageUtil 中,它不会在检测期间使用:

DebugModule {
    @Provide
    ImageUtil imageUtil() {
        if (isTest) {
            return TestImageUtil();
        } else {
            return PicassoImageUtil();
        }
    }
}

有什么建议吗?

更新:在 picasso 的代码中,尝试使用 Executor 而不是 ExecutorService,我卡在了 service.shutdown() 上。

最佳答案

我将向您介绍使用 espresso 等待异步任务的一般方法,因为您可以确定这会再次出现。

您不应该使用线程休眠来等待事情发生。这可能会导致不稳定,并导致您的测试效率降低。 Espresso 的设计考虑到了避免 sleep 调用。

你也不应该强制一些通常不在主线程上的东西在主线程上。如果这导致 ANR,您的测试可能会因为意外的对话框弹出而失败。也可能存在仅在多线程时才会发生的真正错误,但现在您强制在主线程上执行某些操作,您的测试可能会错过它。

您走在正确的轨道上,为 Picasso 换出不同的包装器进行测试。您需要的是一种 Hook 请求何时开始(就在它离开主线程之前)以及请求何时完成的方法。换掉包装器是实现这一目标的一种方法。

要在请求完成时得到通知,您可以使用 callback version of the into method.

现在您已经有了异步任务的入口点和导出点,您可以使用 CountingIdlingResource 来阻止您的测试继续进行,直到任务完成。就像在任务开始前递增计数器并在任务完成时递减一样简单。

这里有一个很好的例子来说明如何使用这个类:https://android.googlesource.com/platform/frameworks/testing/+/android-support-test/espresso/sample/src/androidTest/java/android/support/test/testapp/AdvancedSynchronizationTest.java?autodive=0%2F%2F

关于android - Espresso + picasso + 勺子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31909988/

相关文章:

javascript - 推送通知仅在注销时有效

Android Wifi监听策略

c# - 如何模拟自定义 UserStore 和 RoleStore

ruby-on-rails - 模拟外部 API

java - 模拟框架对我有什么用?

android - 在 Android 上实现位置跟踪

unit-testing - 自动化性能测试

python - 我如何模拟在我的类中使用 requests.get 的方法?

python - Pytest 如何模拟依赖于其父调用参数的函数调用的副作用

Android AWS S3 SDK TransferUtility 在服务中不工作