使用RobolectrictestingViewPager(和CursorLoader)
有谁知道如何使用Robolectrictesting以下设置?
包含ViewPager的片段,用CursorLoader加载的数据。
使用下面的代码,CursorLoader永远不会被推入视图寻呼机的适配器。 我遇到了await()
调用。
EventsFragmentTest.java:
@RunWith(CustomRobolectricTestRunner.class) public class EventsFragmentTest extends AbstractDbAndUiDriver { // which element in the view pager we are testing private static final int TEST_INDEX = 0; protected SherlockFragmentActivity mActivity; protected EventsFragment_ mFragment; @Override @Before public void setUp() throws Exception { // create activity to hold the fragment this.mActivity = CustomRobolectricTestRunner.getActivity(); // create and start the fragment this.mFragment = new EventsFragment_(); } @Test public void sanityTest() { // create an event final Event event = this.createEvent(); // create mock cursor loader final Cursor cursor = this.createMockEventCursor(event); this.mFragment.setCursorLoader(mock(CursorLoader.class)); when(this.mFragment.getCursorLoader().loadInBackground()).thenReturn(cursor); CustomRobolectricTestRunner.startFragment(this.mActivity, this.mFragment); await().atMost(5, SECONDS).until(this.isCursorLoaderLoaded(), equalTo(true)); // check for data displayed final TextView title = this.getTextView(R.id.event_view_title); final TextView text = this.getTextView(R.id.event_view_text); // exists and visible is enough for now this.getImageView(R.id.event_view_image); assertThat(title.getText().toString(), equalTo(event.getTitle())); assertThat(text.getText().toString(), is(event.getText())); // clean up cursor.close(); } @Override protected View getRootView() { return ((ViewPager) this.mFragment.getView().findViewById(R.id.events_pager)).getChildAt(TEST_INDEX); } private Callable<Boolean> isCursorLoaderLoaded() { return new Callable<Boolean>() { public Boolean call() throws Exception { return EventsFragmentTest.this.mFragment.isCursorLoaderLoaded(); // The condition that must be fulfilled } }; } /** * Create an event * * @return */ protected Event createEvent() { // create a random event final Event event = new Event(); event.setImage(null); event.setLink("/some/link/" + RandomUtils.getRandomString(5)); //$NON-NLS-1$ event.setResourceUri("/rest/uri/" + RandomUtils.getRandomDouble()); //$NON-NLS-1$ event.setText("this is a test object " + RandomUtils.getRandomString(5)); //$NON-NLS-1$ return event; } protected Cursor createMockEventCursor(final Event event) { // Create a mock cursor. final Cursor cursor = new CursorWrapper(mock(MockCursor.class)); when(cursor.getCount()).thenReturn(1); when(cursor.getString(cursor.getColumnIndexOrThrow(EventTable.COLUMN_TEXT))).thenReturn(event.getText()); when(cursor.getString(cursor.getColumnIndexOrThrow(EventTable.COLUMN_TITLE))).thenReturn(event.getTitle()); when(cursor.getString(cursor.getColumnIndexOrThrow(EventTable.COLUMN_IMAGE))).thenReturn(event.getImage()); when(cursor.getString(cursor.getColumnIndexOrThrow(EventTable.COLUMN_LINK))).thenReturn(event.getLink()); when(cursor.getString(cursor.getColumnIndexOrThrow(EventTable.COLUMN_RESOURCE_URI))).thenReturn( event.getResourceUri()); // return created event return cursor; } }
EventsFragment.java
@EFragment(resName = "events_fragment") public class EventsFragment extends SherlockFragment implements LoaderCallbacks<Cursor> { @ViewById(R.id.events_pager) protected ViewPager mPager; @ViewById(R.id.events_indicator) protected CirclePageIndicator mIndicator; @Pref protected ISharedPrefs_ mPreferences; protected EventsFragmentAdapter pageAdapter; private CursorLoader mCursorLoader; /** * initialise the cursoradapter and the cursor loader manager. */ @AfterViews void init() { final SherlockFragmentActivity activity = this.getSherlockActivity(); this.pageAdapter = new EventsFragmentAdapter(activity.getSupportFragmentManager(), null); this.mPager.setAdapter(this.pageAdapter); this.mIndicator.setViewPager(this.mPager); this.getLoaderManager().initLoader(this.mPager.getId(), null, this); } /* (non-Javadoc) * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onCreateLoader(int, android.os.Bundle) */ @Override public Loader<Cursor> onCreateLoader(final int arg0, final Bundle arg1) { if (this.mCursorLoader == null) { // set sort to newest first final String sortOrder = BaseColumns._ID + " DESC"; //$NON-NLS-1$ this.mCursorLoader = new CursorLoader(this.getActivity(), EventContentProvider.CONTENT_URI, EventTable.getProjection(), AbstractDbTable.getWhereCondition(null), AbstractDbTable.getWhereArgs(this.mPreferences, null), sortOrder); } return this.mCursorLoader; } /* (non-Javadoc) * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoadFinished(android.support.v4.content.Loader, java.lang.Object) */ @Override public void onLoadFinished(final Loader<Cursor> arg0, final Cursor cursor) { this.pageAdapter.swapCursor(cursor); } /* (non-Javadoc) * @see android.support.v4.app.LoaderManager.LoaderCallbacks#onLoaderReset(android.support.v4.content.Loader) */ @Override public void onLoaderReset(final Loader<Cursor> arg0) { this.pageAdapter.swapCursor(null); } /** * Required for testing only. * * @param cursorLoader */ public void setCursorLoader(final CursorLoader cursorLoader) { this.mCursorLoader = cursorLoader; } /** * Required for testing only. * * @param cursorLoader */ public CursorLoader getCursorLoader() { return this.mCursorLoader; } public boolean isCursorLoaderLoaded() { return (this.pageAdapter.getCursor() != null); } }
我不确定,但我敢打赌,内部代码试图使用AsyncTask
来调用游标加载器的loadInBackground()
方法。 您可能会看到死锁,因为AsyncTask
试图调用onPostExecute()
。 这个调用会尝试在你的主UI线程中运行,这正好是你的testing例程的线程。 这是不可能发生的,因为你在调用堆栈中停留在你的testing例程中。
尝试把你的嘲笑升级到更高的水平,以便在testing的背景中没有真正发生。 谷歌的`AsyncTaskunit testingAndroid死锁'看到其他人遇到类似问题的例子。