Android 回收器查看适配器项目计数在单元测试中返回 0



我正在尝试用AndroidJunit4测试RecyclerView,这是我的测试代码:

@Rule
    public ActivityTestRule<ProductListActivity> rule  = new  ActivityTestRule<>(ProductListActivity.class);
............................
..........................
@Test
    public void ensureDataIsLoadingOnSuccess() throws Exception {
        ProductListActivity activity = rule.getActivity();
        ...........................
        ............
        activity.runOnUiThread(new Runnable() {
        public void run() {
            activity.displayProducts(asList(product1, product2), 0);
        }
    });
        assertEquals(2, mAdapter.getItemCount());
        assertThat(((ProductAdapter) mAdapter).getItemAtPosition(0),sameInstance(product1));
        assertThat(((ProductAdapter) mAdapter).getItemAtPosition(1),sameInstance(product2));

    }

这是我在活动中显示产品((的代码:

@Override
    public void displayProducts(List<Product> products, Integer pageNo) {
        progressBar.setVisibility(View.GONE);
        if (pageNo == 0 && products.size() == 0) {
            noProductTextView.setVisibility(View.VISIBLE);
        } else {
            mProductAdapter.addProduct(products);
            noProductTextView.setVisibility(View.GONE);
            productListView.setVisibility(View.VISIBLE);
        }
    }

它给出的错误如下:

junit.framework.AssertionFailedError: expected:<2> but was:<0>
at junit.framework.Assert.fail(Assert.java:50)
at junit.framework.Assert.failNotEquals(Assert.java:287)
at junit.framework.Assert.assertEquals(Assert.java:67)
at junit.framework.Assert.assertEquals(Assert.java:199)
at junit.framework.Assert.assertEquals(Assert.java:205)
at com.kaushik.myredmart.ui.ProductListActivityTest.ensureDataIsLoadingOnSuccess(ProductListActivityTest.java:94)

请帮助我的代码中有什么问题?

原因是您的浓缩咖啡测试没有等待您的加载任务,这很耗时。您需要使用espresso-idling-resource告诉它等待此任务完成。

然后,您需要一个类来实现IdlingResource并将其声明为活动。

当您的浓缩咖啡测试运行时,它将知道并等待您长时间消耗的任务完成并测试结果。

首先,添加其依赖项。

 compile "com.android.support.test.espresso:espresso-idling-resource:2.2.2"

其次,你需要在文件夹src/main/java/your-package中有两个Java文件。
SimpleCountingIdlingResource.java

public final class SimpleCountingIdlingResource implements IdlingResource {
  private final String mResourceName;
  private final AtomicInteger counter = new AtomicInteger(0);
  // written from main thread, read from any thread.
  private volatile ResourceCallback resourceCallback;
  /**
   * Creates a SimpleCountingIdlingResource
   *
   * @param resourceName the resource name this resource should report to Espresso.
   */
  public SimpleCountingIdlingResource(String resourceName) {
    mResourceName = checkNotNull(resourceName);
  }
  @Override public String getName() {
    return mResourceName;
  }
  @Override public boolean isIdleNow() {
    return counter.get() == 0;
  }
  @Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
    this.resourceCallback = resourceCallback;
  }
  /**
   * Increments the count of in-flight transactions to the resource being monitored.
   */
  public void increment() {
    counter.getAndIncrement();
  }
  /**
   * Decrements the count of in-flight transactions to the resource being monitored.
   *
   * If this operation results in the counter falling below 0 - an exception is raised.
   *
   * @throws IllegalStateException if the counter is below 0.
   */
  public void decrement() {
    int counterVal = counter.decrementAndGet();
    if (counterVal == 0) {
      // we've gone from non-zero to zero. That means we're idle now! Tell espresso.
      if (null != resourceCallback) {
        resourceCallback.onTransitionToIdle();
      }
    }
    if (counterVal < 0) {
      throw new IllegalArgumentException("Counter has been corrupted!");
    }
  }
}

EspressoIdlingResource.java

public class EspressoIdlingResource {
  private static final String RESOURCE = "GLOBAL";
  private static SimpleCountingIdlingResource mCountingIdlingResource =
      new SimpleCountingIdlingResource(RESOURCE);
  public static void increment() {
    mCountingIdlingResource.increment();
  }
  public static void decrement() {
    mCountingIdlingResource.decrement();
  }
  public static IdlingResource getIdlingResource() {
    return mCountingIdlingResource;
  }
}

还行。让我们转到您有耗时任务的活动。首先,将此方法放在底部。

@VisibleForTesting
    public IdlingResource getCountingIdlingResource() {
        return EspressoIdlingResource.getIdlingResource();
    }

在你耗时的任务中。 你应该告诉你的浓缩咖啡像这样等待。

EspressoIdlingResource.increment();
  yourTask.run(new Callback() {
    void onFinish(){
      EspressoIdlingResource.decrement();
    }
  })

最后一步是在 UI 测试类中定义这些方法。

@Before
public void registerIdlingResource() {
    Espresso.registerIdlingResources(mOnBoardActivityTestRule.getActivity().getCountingIdlingResource());
}
/**
 * Unregisters your idling resource so it can be garbage collected and does not leak any memory
 */
@After
public void unregisterIdlingResource() {
    Espresso.unregisterIdlingResources(mOnBoardActivityTestRule.getActivity().getCountingIdlingResource());
}

是的。终于我们做到了。

我在这里可以看到一个问题,您在主/UI 线程能够更新它之前正在查询列表大小。因此,您必须在当前线程中等待,直到活动完成主线程上的列表更新。

你可以做到,

Thread.sleep(500);

在 Test 类中等待,在 Activity 中测试列表设置行为,您会发现断言是有效的。

由于主线程无限运行,直到应用程序运行,因此您必须实现 Activity 提供的回调接口,以便在填充列表完成时收到通知。

相关内容

  • 没有找到相关文章

最新更新