Android robolectric and Transformation – waiting for response
I want to test whether my code correctly downloads data from the API (using retrofit) and displays it in recyclerview. To do this, I created an interceptor that imitates the API (based on this solution) and created a test (using robolectric):
@Test
public void listLoadedCorrectly@R_403_1570@ {
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());
}
The problem is that the test sometimes passes and sometimes fails. I have debugged the code. I know this is because the data in mylistfragment has been loaded into RV using retrofit's enqueue () method_ Fruits in recyclerview. How do I wait for the retrofit callback to check the assertion after loading data into recyclerview?
resolvent:
Robolectric tries to synchronize all execution, because asynchronous code will lead to unstable testing. If you use standard tools such as asyntask, but do not modify it, the effect is very good
One way is to hide some retrofit (or okhttp) classes, which execute requests in the new thread and directly execute them. For example, shadowasynctask executes all executable commands in the main thread instead of using the new thread as in the original implementation
Another method is the idlingresource concept used by espresso. Whenever you start a request, then increase the counter on the singleton object and decrease the counter when the request is completed. In the test, you can wait until the counter is zero
The simple way, but the bad way will be a simple sleep