有谁知道如何使用Robolectric测试以下设置?
包含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);
}
}
6
看来您正在尝试编写更多的系统测试而不是单元测试,这是正确的假设吗?如果是这样,可以使用Robotium或Espresso轻松完成。当您尝试编写具有Android特定参考但未测试用户将看到的内容的单元测试或集成测试时,Robolectric确实很有帮助。
—
Elliott
我想念一下,Robolectric试图帮助您测试用户所看到的内容。我认为您会遇到的问题是,您不得不编写过多的引导捆绑代码,这些代码无法在生产中测试正确的代码路径,并且尝试使用定时等待通常会使测试变得脆弱,因为您无法得知如何长时间的异步任务将需要。
—
Elliott 2014年
我正在尝试进行快速测试。我可以而且经常在Robotium中编写测试,但是它们的运行速度比Robolectric慢得多。对我而言,理想的世界是无需设置,支持和维护2组测试。这是我的意图。
—
科里·斯科特
只是一个想法,
—
-weston
Robolectric.runBackgroundTasks();
任何好的东西-可能不是await
我同意@Elliott,您正在尝试创建集成测试或方案测试(例如单元测试),这并不是要使用的,如果您想破解\滥用robolectric罚款,但这是有代价的。robolectric仅提供存根,而不提供类。
—
codeScriber