Kotlin之协程(第三趴)——通过行为测试协程

138 阅读2分钟

本博客将为上一篇博客Kotlin之协程(第二趴)——使用协程控制界面编写的代码编写测试。将使用kotlinx-coroutines-test库测试在Dispatchers.Main上运行的协程。

1、查看现有代码

打开androidTest文件夹中的MainViewModelTest.kt MainViewModelTest.kt

class MainViewModelTest {
    @get:Rule
    val coroutineScope = MainCoroutineScopeRule()
    @get:Rule
    val instantTaskExecutorRule = InstantTaskExecutorRule()
    
    lateinit var subject: MainViewModel
    
    @Before
    fun setup() {
        subject = MainViewModel(
            TitleRepository(
                MainNetworkFake("OK"),
                TitleDaoFake("initial")
            )
        )
    }
}

规则是一种在JUnit中进行测试之前和之后运行代码的方式。我们利用以下两个规则在设备外测试中测试MainViewModel:

  1. InstantTaskExecutorRule是一种JUnit规则,用于配置LiveData以同步执行每项任务。
  2. MainCoroutineScopeRule是此代码库中的自定义规则,用于将Dispatchers.Main配置为使用kotlinx-coroutines-test中的TestCoroutineDispatcher。这样依赖,测试可以将用于测试的虚拟时钟拨快,并让代码可以使用单元测试中的Dispatchers.Main

setup方法中,系统使用测试虚构对象创建一个新的MainViewModel实例。这些对象时在起始代码中提供的网络和数据库的虚构实现,以帮助在不使用时机网络或数据库的情况下编写测试。

对于此测试,只需要将一来虚拟对象来满足MainViewModel的依赖项要求。

2、编写用于控制协程的测试

添加一项新的测试,以确保系统在用户点按主视图的一秒钟后更新点按计数: MainViewModelTest.kt

@Test
fun whenMainClicked_updatesTaps() {
    subject.onMainViewClicked()
    Truth.assertThat(subject.taps.getValueForTest()).isEqualTo("0 taps")
    coroutineScope.advanceTimeBy(1000)
    Truth.assertThat(subject.taps.getValueForTest()).isEqualTo("1 taps")
}

通过调用onMainViewClicked,提供将启动我们刚刚创建的协程。此测试用于检查是否出现以下情况: 点按计数文字在系统调用onMainViewClicked后保持"0 taps"不变,然后再1秒钟后更新为“1 taps”。

此测试使用虚拟时间控制onMainViewClicked所启动的协程的执行。使用MainCoroutineScopeRule,您可以暂停、恢复或控制在Dispatchers.Main上启动的协程的执行。在这里,我们将调用advanceTieBy(1_000),这会导致主调度程序立即执行预定在1秒后恢复的协程。

此测试具有完全确定性,这意味着它将始终以相同的方式执行。此外,由于测试完全控制在Dispatchers.Main上启动的协程的执行,因此无需等待一秒钟,即可设置值。

3、运行现有测试

  1. 右键点击编辑器中的类名称MainViewModelTest,以打开上下文菜单。
  2. 在上下文菜单中,选择execute.pngRun ‘MainViewModelTest'
    1. 今后运行测试时,您可以在工具栏中 execute.png 按钮旁边的配置中选择此测试配置。默认情况下,此配置将称为 MainViewModelTest

您应该会看到测试通过!实际运行时间应该比 1 秒钟短一些。