Robolectric ShadowAsyncTask 在暂停模式下不支持此操作

Robolectric ShadowAsyncTask this action is not supported in PAUSED mode

以下一直在为 Robolectric 4.2

工作
@Implements(AsyncTask.class)
public class MyShadowAsyncTask<Params, Progress, Result>
    extends ShadowAsyncTask<Params, Progress, Result> {

  @Implementation
  @SuppressWarnings("unchecked")
  public AsyncTask<Params, Progress, Result> executeOnExecutor(
      Executor executor, Params... params) {
    return super.execute(params);
  }
}

方法 .execute 似乎不再存在于 4.4 中

所以我试过了

  1. ShadowLegacyAsyncTask
@Implements(AsyncTask.class)
public class CmbShadowAsyncTask<Params, Progress, Result>
    extends ShadowLegacyAsyncTask<Params, Progress, Result> {

  @Implementation
  @SuppressWarnings("unchecked")
  public AsyncTask<Params, Progress, Result> executeOnExecutor(
      Executor executor, Params... params) {
    return super.executeOnExecutor(executor, params);
  }
}

找到我了

Exception in thread "AsyncTask #1" java.lang.RuntimeException: java.lang.UnsupportedOperationException: post is not supported in PAUSED LooperMode
    at org.robolectric.shadows.ShadowLegacyAsyncTask.done(ShadowLegacyAsyncTask.java:66)
    at java.base/java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:381)
    at java.base/java.util.concurrent.FutureTask.set(FutureTask.java:232)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:272)
    at org.robolectric.shadows.ShadowLegacyAsyncTask.run(ShadowLegacyAsyncTask.java:127)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.UnsupportedOperationException: post is not supported in PAUSED LooperMode
    at org.robolectric.android.internal.LooperDelegatingScheduler.post(LooperDelegatingScheduler.java:62)
    at org.robolectric.shadows.ShadowLegacyAsyncTask.done(ShadowLegacyAsyncTask.java:43)
    ... 7 more

this action is not supported in PAUSED mode.
java.lang.IllegalStateException: this action is not supported in PAUSED mode.
    at org.robolectric.shadows.ShadowLooper.assertLooperMode(ShadowLooper.java:27)
    at org.robolectric.shadows.ShadowApplication.getBackgroundThreadScheduler(ShadowApplication.java:113)
    at org.robolectric.shadows.ShadowLegacyAsyncTask.execute(ShadowLegacyAsyncTask.java:104)
    at android.os.AsyncTask.execute(AsyncTask.java)
  1. ShadowPausedAsyncTask
@Implements(AsyncTask.class)
public class CmbShadowAsyncTask<Params, Progress, Result>
    extends ShadowPausedAsyncTask<Params, Progress, Result> {

  @Implementation
  @SuppressWarnings("unchecked")
  public AsyncTask<Params, Progress, Result> executeOnExecutor(
      Executor executor, Params... params) {
    return super.executeOnExecutor(executor, params);
  }
}

找到我了

this action is not supported in PAUSED mode.
java.lang.IllegalStateException: this action is not supported in PAUSED mode.
    at org.robolectric.shadows.ShadowLooper.assertLooperMode(ShadowLooper.java:27)
    at org.robolectric.shadows.ShadowApplication.getBackgroundThreadScheduler(ShadowApplication.java:113)
    at org.robolectric.Robolectric.getBackgroundThreadScheduler(Robolectric.java:346)
    at org.robolectric.Robolectric.flushBackgroundThreadScheduler(Robolectric.java:353)

Java 版本 11 Gradle 版本 6.7.1 AGP 版本 4.3.1

根据 Robolectric 的维护者,迁移步骤是

  1. 已使用 ShadowLegacyAsyncTask
  2. 每次测试使用 @LooperMode(LEGACY)
  3. shadowOf(Looper.getMainLooper()).idle()添加到每个测试中的每个触发器

参考:https://github.com/robolectric/robolectric/issues/6925