Testen eines CursorLoaders mit Robolectric & Mockito

Angesichts der Tatsache, dass ich ein einfaches ListFragment entwickle (in diesem Fall liest es eine Liste der Interpreten aus dem MediaStore, liest aber später auch Daten aus einer anderen Quelle):

@EFragment
public class ArtistsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
    private static final String TAG = ArtistsFragment.class.getName();
    private SimpleCursorAdapter mAdapter;

    Uri uri = MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI;

    CursorLoader mCursorLoader;

    @AfterViews
    void setupView() {
        mAdapter = new SimpleCursorAdapter(getActivity(),
                android.R.layout.simple_list_item_1, null,
                new String[]{MediaStore.Audio.Artists.ARTIST}, // lists path of files
                new int[]{android.R.id.text1}, 0);

        setListAdapter(mAdapter);

        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        if (mCursorLoader == null) {
            mCursorLoader = new CursorLoader(getActivity(), uri, new String[]{MediaStore.Audio.Artists._ID, MediaStore.Audio.Artists.ARTIST},
                    null, null, MediaStore.Audio.Artists.ARTIST + " ASC");
        } else {
            System.out.println("mCursorLoader.count: " + mCursorLoader.loadInBackground().getCount());            
        }
        return mCursorLoader;
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        setListShown(true);
        mAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mAdapter.swapCursor(null);
    }
}

Ich möchte benutzenRobolectric + Mockito + Erwartung um zu prüfen, ob sich das Fragment unter verschiedenen Bedingungen richtig verhält (z. B. leere Liste oder ungültige Daten usw.). Meine Testklasse sieht so aus:

@RunWith(RobolectricTestRunner.class)
public class ArtistsFragmentTest {
    @Test
    public void shouldNotBeNull() {
        final ArtistsFragment myFragment = ArtistsFragment_.builder().build();
        assertNotNull(myFragment);

        // Create a mock cursor.
        final Cursor mc = getSampleArtistCursor();
        when(mc.getCount()).thenReturn(1);
        when(mc.getInt(0)).thenReturn(1);
        when(mc.getString(1)).thenReturn("Sample Title");

        myFragment.mCursorLoader = mock(CursorLoader.class);
        when(myFragment.mCursorLoader.loadInBackground()).thenReturn(mc);

        startFragment(myFragment);

        assertNotNull(myFragment.getListView());
        await().atMost(5, TimeUnit.SECONDS).until(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return myFragment.getListAdapter().getCount();
            }
        }, equalTo(1));

        System.out.println(myFragment.getListAdapter().getCount());
    }

    private Cursor getSampleArtistCursor() {
        return new CursorWrapper(mock(MockCursor.class));
    }
}

Wenn dieser Test in IntelliJ oder maven ausgeführt wird, schlägt der Test fehl, und der Adapter gibt immer eine Zählung von Null zurück.

Die Anweisung System.out.println in onCreateLoader gibt jedoch zurück1. Muss ich besonders auf Mockito aufpassen?Hintergrund-Threads? (Die loadInBackground-Methode wird in einem Arbeitsthread ausgeführt.)

Antworten auf die Frage(2)

Ihre Antwort auf die Frage