android-Robolectric和改造-等待响应

我想测试我的代码是否正确地从API下载了数据(使用Retrofit)并将其显示在RecyclerView中.为了做到这一点,我创建了一个模仿API的拦截器(基于this solution)并创建了一个测试(使用Robolectric):

    @Test
    public void listLoadedCorrectlyTest() {
        MyListFragment myListFragment = new MyListFragment();
        Bundle args = new Bundle();
        FragmentTestUtil.startFragment(myListFragment);
        Robolectric.flushForegroundThreadScheduler();
        JSONArray responseArray = new JSONArray();
        try {
            responseArray = new JSONArray(ApiInterceptor.MOCK_RESPONSE);
        } catch (JSONException e) {
            Log.e("JSON", e.getMessage());
        }
        int adapterItemCount = ((RecyclerView) myListFragment.getView()
                .findViewById(R.id.rv_fruits)).getAdapter().getItemCount();
        assertThat(adapterItemCount).isEqualTo(responseArray.length());
    }

问题是测试有时会通过,有时会失败.我已经调试了代码,我知道这是因为MyListFragment中的数据已使用Retrofit的enqueue()方法加载到rv_fruits RecyclerView中.我如何等待Retrofit回调,以便在将数据加载到RecyclerView之后检查断言?

解决方法:

Robolectric尝试使所有执行同步,因为异步代码会导致不稳定的测试.如果您使用AsynTask之类的标准工具,但改装却不做,则效果很好.

一种方法是隐藏某些Retrofit(或OkHttp)类,这些类在新线程中执行请求,而直接执行它们.例如,ShadowAsyncTask在主线程中执行所有可运行的命令,而不是像原来的实现那样使用新线程.

另一种方法是Espresso使用的IdlingResource概念.每当您启动请求时,然后在单例对象上增加计数器,并在请求完成时减少计数器.在测试中,您可以等待直到计数器为零.

简单的方法,但不好的做法将是一个简单的睡眠.

上一篇:Android的 – 是什么让改装比HttpURLConnection类的AsyncTask快?


下一篇:改造2入队方法运行2次