Robolectric无法在后台线程上调用setValue

问题描述 投票:0回答:1

我正在测试AsyncTask,其中onPostExecute调用了setValue实例的LiveData。由于我正在从setValue调用onPostExecute,因此不会出现关于由UI线程进行的调用的问题。

但我已经在Robolectric单元测试中运行它:java.lang.IllegalStateException: Cannot invoke setValue on a background thread

为了使此单元测试等待后台和前台任务完成,我通过以下方式利用了等待工具:

var cf = new CompletableFuture<T>();
livedata.observe(ctrl.get(), it -> cf.complete(it));
// ... perform the AsyncTask that will update livedata in onPostExecute
await().until(() -> {
    flushBackgroundThreadScheduler()
    flushForegroundThreadScheduler()
    cf.isDone
});

这在IllegalStateException: Cannot invoke setValue on a background thread通话中抛出了flushForegroundThreadScheduler() !!!!

为什么我会收到此例外?以及如何像UI线程一样执行onPostExecute

UPDATE

正在记录线程,看来flushBackgroundThreadScheduler()flushForegroundThreadScheduler()都是内联同步执行的。我可以观察到:

LiveData created on thread 763324286
Background thread 1519527121
LiveData updated on thread 1519527121

由于传递给await.until的lambda在另一个线程上运行,所以flushBackgroundThreadScheduler()flushForegroundThreadScheduler()都在该线程1519527121上执行。

因此,我可以通过在与UI线程相对应的测试线程中运行以下变通办法来解决我的问题。但是,我需要Thread.sleep()才能成功,但我不喜欢它。

Thread.sleep(1000)
flushBackgroundThreadScheduler()
flushForegroundThreadScheduler()
cf.isDone
android android-asynctask robolectric android-livedata androidx-test
1个回答
0
投票

我们必须考虑以下因素:

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.