runTest未在主线程运行致报错,如何让测试用例成功执行?
解决测试中
addObserver需主线程执行的问题 你遇到的java.lang.IllegalStateException: Method addObserver must be called on the main thread错误,根源是runTest默认使用测试专用的协程调度器,并非Android主线程(关联Main Looper的线程)。以下是几种可行的解决方法:
方法一:使用InstantTaskExecutorRule(JUnit4适用)
在测试类中添加该Rule,它会强制LiveData等组件的操作在当前测试线程同步执行,且该线程会被识别为主线程:
@get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @Test fun useAppContext() = runTest { assert(isMainThread()) // 在此处调用addObserver操作 }
方法二:指定Dispatchers.Main为测试调度器
通过设置主线程调度器的测试实现,让runTest在主线程上下文中执行:
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.setMain import org.junit.After import org.junit.Before import org.junit.Test class YourTestClass { @Before fun setup() { Dispatchers.setMain(StandardTestDispatcher()) } @After fun teardown() { Dispatchers.resetMain() } @Test fun useAppContext() = runTest { assert(isMainThread()) // 执行addObserver操作 } }
也可以直接在runTest中指定调度器:
@Test fun useAppContext() = runTest(Dispatchers.Main) { assert(isMainThread()) }
方法三:使用runOnUiThread(Instrumented测试适用)
如果是在真实设备/模拟器上运行的Instrumented测试,可直接将代码块切换到主线程执行:
@Test fun useAppContext() { runOnUiThread { assert(isMainThread()) // 调用addObserver } }
内容的提问来源于stack exchange,提问作者NoKey
相关产品推荐
相关产品推荐

