当前位置: 首页 > 知识库问答 >
问题:

机器人和改装-等待响应

朱鹤轩
2023-03-14

我想测试我的代码是否正确地从API下载数据(使用改装),并在RecyclerView中显示它们。为了做到这一点,我创建了一个模拟API的拦截器(基于此解决方案),并创建了一个测试(使用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中的数据是使用Reformation的enqueue()方法加载到rv\U fruits中的。如何等待改装回调,以便在数据加载到RecyclerView后检查断言?

共有3个答案

殷耀
2023-03-14

我发现在Retrofit(带有回调)中使用Robolectic的主要问题。但是,当您使用RestAdapter设置RestAdapter时。Builder您可以有条件地修改它(NB永远不会在您的实际应用程序中使用此配置):

if(singleThreaded){
    Executor executor = Executors.newSingleThreadExecutor();
    restAdapterBuilder.setExecutors(executor, executor);
}

通过为请求和回调添加这个单线程执行器,所有测试异步代码的标准方法(例如使用Countdownlock)都将起作用。

骆磊
2023-03-14

Robolectric试图使所有执行同步,因为异步代码会导致不稳定的测试。如果您使用AsynTask之类的标准工具,这很好用,但改型不起作用。

一种方法是隐藏一些在新线程中执行请求的改装(或OkHttp)类,而不是直接执行它们。例如,ShadowAsyncTask在主线程中执行所有可运行的任务,而不是使用新线程,这是原始实现将如何执行的。

另一种方法是与Espresso一起使用的IdlingResources概念。每当您开始一个请求时,然后在单例对象上增加一个计数器,当请求完成时减少计数器。在您的测试中,您可以等到计数器为零。

简单的方法,但不好的做法是简单的睡眠。

秦承允
2023-03-14

另一种方法:

我一直在非常成功地使用免责工具。它本质上与闩锁相同,但更具可读性。

在您的情况下:

@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();
    await().atMost(15, TimeUnit.SECONDS)
                      .until(responseIsSameAsCount(myListFragment, responseArray)
}


    private Callable<Boolean> responseIsSameAsCount(View myListFragment, JSONArray responseArray) {
    return new Callable<Boolean>() {
        @Override
        public Boolean call() throws Exception {
            return  ((RecyclerView) myListFragment.getView()
            .findViewById(R.id.rv_fruits)).getAdapter().getItemCount() == responseArray.length();
        }
    };
}
 类似资料:
  • 我已经建立了一个不和谐,但是使用javascript,我有一个命令,我希望能够搜索youtube视频,并在语音频道中播放第一个结果。 我正在使用discordjs和discord-youtup-api库。 此代码查找要搜索的命令。args数组是搜索查询 这就是使用youtube api搜索视频并返回其网址的功能。 尝试该命令时,我确实收到以下错误消息。 我猜问题在于,音乐机器人试图在searchY

  • 问题内容: 我有一个页面,使用被称为100次(async:true)的jQuery.ajax,问题是,当它们都被加载时,我需要系统等待所有100次调用返回后才能继续。我将如何处理? 提前致谢!:) 更新: 这些调用在for()循环中进行(其中有100个:) 问题答案: 最好的方法是使用。您可以按以下方式使用它: 另外,如果您在数组中拥有所有AJAX调用,则可以使用: 请注意,这至少需要jQuery

  • 我有一个项目,我需要使用一个站点从中获取数据。所以事情是这样的:使用htmlUnit我用我的数据填充文本框,然后我按下锚,它使用ajax下载我需要的内容并动态更改超文本标记语言页面,在模态窗口中显示内容。但是在我使用锚上的. Click()后,我得到了相同的页面,没有更新,在寻找解决方案后,我在网络上发现了这个: HtmlUnit将执行Ajax调用并更新页面。请注意,与常规页面加载不同,Click

  • 我正在使用discordpy编写一个discord测验机器人。机器人发送一条包含问题和4个可能答案的消息。机器人还使用表情符号1为其信息添加反应️⃣, 2.️⃣, 3.️⃣ 四,️⃣. 这个想法是,机器人等待30秒,让人们点击其中一个反应。如果单击的反应是正确/错误的答案,则bot会回答正确或错误。一旦有人回答,机器人也应该停止等待新的反应。Aka:一旦有人点击了4个反应表情中的一个,机器人就会回

  • 问题内容: 我的页面运行着一系列命令,这些命令迫使我的PHP脚本停止更改,直到收到响应为止。我如何知道不要等待响应而只运行命令? 我正在使用一个具有后端系统的复杂命令,我可以查询该命令以检查状态,因此我不关心响应。 问题答案: 取决于您使用的平台和运行的命令。 例如,在Unix / Linux上,您可以在命令末尾追加命令,以告诉Shell释放您已启动的进程,exec将立即返回。这在Windows上

  • 我们正在创建一个不和谐机器人。 问题是控制台中没有错误,但不和谐聊天也是空的。所以完全没有回应。你能帮我说说我的错误是什么以及如何解决这个问题吗 祝你一切顺利,尼克斯