簡體   English   中英

使用Robolectric通過Loader測試活動

[英]Use Robolectric to test Activity with Loader

我有一個帶有Spinner的Activity,該Activity使用Loader從ContentProvider中獲取數據(如在多個資源中所建議的那樣,正如我之前所做的那樣):

protected void onCreate(Bundle savedInstanceState) {

  // ...

  account = (Spinner) findViewById(R.id.account);
  account.setAdapter(
    new SimpleCursorAdapter(
      this,
      android.R.layout.simple_spinner_item,
      null,
      new String[]{ Contract.Accounts.COL_NAME },
      new int[]{ android.R.id.text1 },
      0));

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

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
  return new CursorLoader(this,
    Contract.Accounts.CONTENT_URI,
    null,
    null,
    null,
    null);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
  ((SimpleCursorAdapter)account.getAdapter()).swapCursor(data);
}

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

到目前為止,我運行該應用程序時,它的工作原理像一個超級工具,但是我現在無法運行此活動的單元測試。

@Test
public void testAllElementsExist() {
  Activity activity = setupActivity(AddTransactionActivity.class);

  assertTrue(activity.findViewById(R.id.category) != null);
  assertTrue(activity.findViewById(R.id.created_on_date) != null);
  assertTrue(activity.findViewById(R.id.created_on_time) != null);
  assertTrue(activity.findViewById(R.id.account) != null);
  assertTrue(activity.findViewById(R.id.description) != null);
}

即使是最基本的測試也會失敗:

java.lang.NullPointerException
at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:328)
at android.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:345)
at pt.lemonade.AddTransactionActivity.onLoadFinished(AddTransactionActivity.java:185)
at pt.lemonade.AddTransactionActivity.onLoadFinished(AddTransactionActivity.java:28)
at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:482)
at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:450)
at android.content.Loader.deliverResult(Loader.java:143)
at android.content.CursorLoader.deliverResult(CursorLoader.java:113)
at android.content.CursorLoader.deliverResult(CursorLoader.java:43)
at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:254)
at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:91)
at android.os.ShadowAsyncTaskBridge.onPostExecute(ShadowAsyncTaskBridge.java:22)
at org.robolectric.shadows.ShadowAsyncTask$1$1.run(ShadowAsyncTask.java:40)
at org.robolectric.util.Scheduler$PostedRunnable.run(Scheduler.java:182)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:125)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:110)
at org.robolectric.util.Scheduler.advanceToLastPostedRunnable(Scheduler.java:86)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:26)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:231)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:270)
at org.robolectric.util.ActivityController.visible(ActivityController.java:166)
at org.robolectric.util.ActivityController.setup(ActivityController.java:202)
at org.robolectric.Robolectric.setupActivity(Robolectric.java:1388)
at pt.lemonade.AddTransactionActivityTest.testAllElementsExist(AddTransactionActivityTest.java:65)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:236)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:158)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

這是Robolectric 2.4的已知問題嗎? 有沒有一種解決方法不能轉化為編寫一堆影子類?

交易工具:已啟用單元測試實驗功能的Android Studio 1.1.0,Gradle插件1.0.1,Robolectric 2.4

另外,還有一些疑問:我最近聽說最好使用RxJava Observables,因為它更容易測試。 可以代替LoaderManager嗎? 如何像LoaderManager一樣緩存結果? 您能給我一個對ContentProvider進行查詢的有效示例以及一個單元測試,以便我進行評估嗎?

如果有人遇到同樣的問題: Robolectric缺少ShadowSimpleCursorAdapter#swapCursor實現。 我已經將該方法與其他修改一起添加,並創建了請求請求。 您可以在master分支中找到它。 至於仍在使用2.4版的任何人,請查看以下內容: https : //github.com/robolectric/robolectric/issues/1677

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM