Issue
I would like to test if my code is correctly downloading data from API (using Retrofit) and displays them in RecyclerView. In order to do this I created an interceptor which mocks API (basing on this solution) and created a test (using 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());
}
The problem is that the test is sometimes passed and sometimes failed. I've debugged the code and I know that this is because the data in MyListFragment are loaded to the rv_fruits RecyclerView using Retrofit's enqueue() method. How can I wait for the Retrofit callback so that the assertion is checked AFTER the data are loaded to the RecyclerView?
Solution
Robolectric tries to make all execution synchron because async code leads into flaky tests. This works fine if you use standard stuff like AsynTask but retrofit don't do it.
One approach is to shadow some Retrofit (or OkHttp) classes which execute the request in a new thread and instead execute them directly. For example ShadowAsyncTask execute all runnable in main thread instead of using new thread how it the original implementation would do it.
Another approach is the IdlingResource concept which is used with Espresso. Whenever you start an request then increment a counter on a singleton object and when the request finished decrement the counter. In your tests you can then wait until the counter is zero.
Easy approach but bad practice would be a simple sleep.
Answered By - nenick
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.