0

在我的 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
4

1 回答 1

0

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

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

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

    @JvmField
    val instantExecutorRule = InstantTaskExecutorRule()

    @ExperimentalCoroutinesApi
    @get:Rule
    var mainCoroutineRule = MainCoroutineRule()
于 2020-06-13T11:11:37.003 回答