【问题标题】:How to test a function running a coroutine in an Android instrumented test?如何在 Android 检测测试中测试运行协程的函数?
【发布时间】:2020-06-13 10:24:17
【问题描述】:

在我的 Android Kotlin 项目中,我有一个类,它有一个运行协程的函数,我想使用插桩测试(而不是单元测试)对其进行测试。

这是它的样子:

class DemoClass
{
    fun demo(liveData: MutableLiveData<String>)
    {
        CoroutineScope(IO).launch {
            val result = doStuff()
            withContext(Main) { liveData.value = result }
        }
    }
}

在我的仪器测试类中,这是我尝试过的:

@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest
{
    @ExperimentalCoroutinesApi
    @Test
    fun testCoroutine() = runBlockingTest {
        val demoClass = DemoClass()
        val liveData = MutableLiveData<String>()
        demoClass.demo(liveData)
        assertEquals("demo", liveData.value)
    }
}

很遗憾,它不起作用。似乎runBlockingTest {} 仅可用于单元测试,不能用于仪器测试。这是我运行测试时的错误:

java.lang.NoClassDefFoundError: Failed resolution of: Lkotlinx/coroutines/test/TestBuildersKt;

那么如何在仪器测试中测试DemoClass.demo()liveData 值?

谢谢。

编辑

我也试过这个:

@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest
{
    private val testDispatcher = TestCoroutineDispatcher()

    @Before
    fun setup() {
        Dispatchers.setMain(testDispatcher)
    }

    @After
    fun tearDown() {
        Dispatchers.resetMain()
        testDispatcher.cleanupTestCoroutines()
    }

    @Test
    fun testCoroutine(): Unit = runBlocking {
        val demoClass = DemoClass()
        val liveData = MutableLiveData<String>()
        demoClass.demo(liveData)
        assertEquals("demo", liveData.value)
    }
}

测试运行,但我得到了这个:

java.lang.AssertionError: 
Expected :demo
Actual   :null

【问题讨论】:

    标签: android kotlin kotlin-coroutines instrumented-test


    【解决方案1】:

    我一直在使用 runBlocking {} 而不是 runBlockingTest 来成功。

    我知道从技术上讲 runBlockingTest 是正确的方法,我认为主要区别在于处理延迟的方式。

    可能在您的测试类中尝试这些标志来绕过这种差异,

        @JvmField
        val instantExecutorRule = InstantTaskExecutorRule()
    
        @ExperimentalCoroutinesApi
        @get:Rule
        var mainCoroutineRule = MainCoroutineRule()
    

    【讨论】:

    • 仍然不适合我。你能提供一个小例子吗?
    • 嗯,您是否已验证您的 build.gradle 中有 androidTestImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.7' ?还添加了更多细节
    • 谢谢,是的,我有那个实现,但我仍然无法让它工作(它是 testImplementation,顺便说一句)。我编辑了我的帖子,供您参考。
    • 如果您希望库可用于仪器测试而不是单元测试,您应该按照 Mike 的建议使用 androidTestImplementation
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-09
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 2019-02-10
    相关资源
    最近更新 更多