2018年6月20日水曜日

LiveData を UnitTest でテストする

デザートの文字列を保持して、追加・削除されたタイミングで保持数を LiveData で通知する DessertsHolder を UnitTest でテストしてみましょう。
  1. class DessertsHolder {  
  2.   
  3.     private val counter = MutableLiveData<Int>()  
  4.     private val list = mutableListOf<String>()  
  5.   
  6.     init {  
  7.         counter.value = 0  
  8.     }  
  9.   
  10.     fun getCounter(): LiveData<Int> = counter  
  11.   
  12.     fun add(item: String) {  
  13.         list.add(item)  
  14.         counter.value = list.size  
  15.     }  
  16.   
  17.     fun remove(item: String) {  
  18.         list.remove(item)  
  19.         counter.value = list.size  
  20.     }  
  21.   
  22.     fun clear() {  
  23.         list.clear()  
  24.         counter.value = 0  
  25.     }  
  26. }  
特に何もせず次のような普通の UnitTest を書くと、Looper が mock されていないというエラー(RuntimeException: Method getMainLooper in android.os.Looper not mocked. )がでます。
  1. class DessertsHolderTest {  
  2.   
  3.     @Test  
  4.     fun test() {  
  5.         val holder = DessertsHolder()  
  6.   
  7.         holder.add("Donuts")  
  8.   
  9.         assertThat(holder.getCounter().value).isEqualTo(1)  
  10.     }  
  11. }  


そこで、まず AAC の core-testing ライブラリを追加します。
  1. dependencies {  
  2.     def lifecycle_version = "1.1.1"  
  3.     testImplementation "android.arch.core:core-testing:$lifecycle_version"  
  4. }  
AndroidX
  1. dependencies {  
  2.     def lifecycle_version = "2.0.0"  
  3.     testImplementation "androidx.arch.core:core-testing:$lifecycle_version"  
  4. }  

そして @get:Rule で rule に InstantTaskExecutorRule を指定します。このとき get: をつけないと rule が public ではないという ValidationError (ValidationError: The @Rule 'rule' must be public.)が起こるので注意しましょう。
  1. class DessertsHolderTest {  
  2.   
  3.     @get:Rule  
  4.     val rule: TestRule = InstantTaskExecutorRule()  
  5.   
  6.     @Test  
  7.     fun test() {  
  8.         ...  
  9.     }  
  10. }  



0 件のコメント:

コメントを投稿