Skip to main content

AndroidのLiveDataに対してJUnitを実行する

非同期で処理するLiveDataはテストしにくい・・・。
それでもテストしなきゃいけない!
そんなわけでやり方を調べた


・コード

class MainManager {
    private val _a = MutableLiveData<String>()
    val a: LiveData<String> = _a

    fun send() {
        _a.value = "masterka"
    }
}

 

・Junit4

class MainManagerTest {

    @Rule
    @JvmField
    val instantTaskExecutorRule = InstantTaskExecutorRule()

    @Test
    fun livedataTest() {
        val manager = MainManager()

        val mockObserver = spyk<Observer<String>>()
        manager.a.observeForever(mockObserver)

        manager.send()

        verify { mockObserver.onChanged("masterka") }
    }
}

参考
https://star-zero.medium.com/livedata%E3%81%AEunittest-2b295d2818c1
https://qiita.com/HanaleiMoon/items/375e42a9fc5e635d02c9
@Ruleはロジックを書く
https://teratail.com/questions/2340
InstantTaskExecutorRuleは以下の意味
https://star-zero.medium.com/livedata%E3%81%AEunittest-2b295d2818c1

 

・Junit5

@ExtendWith(value = [InstantExecutorExtension::class])
class MainManager2Test {

    @Test
    fun livedataTest() {
        val manager = MainManager()

        val mockObserver = spyk<Observer<String>>()
        manager.a.observeForever(mockObserver)

        manager.send()

        verify { mockObserver.onChanged("msterka") }
    }
}


class InstantExecutorExtension : BeforeEachCallback, AfterEachCallback {

    override fun beforeEach(context: ExtensionContext?) {
        ArchTaskExecutor.getInstance()
            .setDelegate(object : TaskExecutor() {
                override fun executeOnDiskIO(runnable: Runnable) = runnable.run()

                override fun postToMainThread(runnable: Runnable) = runnable.run()

                override fun isMainThread(): Boolean = true
            })
    }

    override fun afterEach(context: ExtensionContext?) {
        ArchTaskExecutor.getInstance().setDelegate(null)
    }
}

参考
https://jeroenmols.com/blog/2019/01/17/livedatajunit5/

 

・エラー
Method getMainLooper in android.os.Looper not
が出たら
testImplementation “androidx.arch.core:core-testing:2.1.0”
で修正できる
https://stackoverflow.com/questions/58057769/method-getmainlooper-in-android-os-looper-not-mocked-still-occuring-even-after-a

関連記事:

Pocket