Using Mockito

Mockito 是一個常見的 testing framework,這邊稍微紀錄一下我用到的測試寫法,包括

  1. change private variable
  2. specify return value
  3. to verify whether a method is invoked
  4. to verify parameters of a method call

修改 private variable#

假設要修改物件 mObject 的 private String mFoofoobar。這邊會用到 Whitebox,也就是說會破壞物件的封裝,盡量不要過度使用

1
Whitebox.setInternalState(mObject, "mFoo", "foobar");

修改物件的回傳值#

舉例來說,想要測試的程式碼如果呼叫到 mObject 的 method isInitialized(),可以指定回傳值為 true。如果我們不需要真正會動的 mObject,這樣就不用花一堆時間在 mObject 的初始化上面

1
doReturn(true).when(mObject).isInitialized();

測試 method call 有被執行#

跑完一個測項之後,想要確認某一個 method 是不是有被執行,舉例來說,是不是真的有呼叫一次 [Service.startActivity](https://developer.android.com/reference/android/app/Service.html#startForeground(int,%20android.app.Notification)。底下的例子中,我們並不在乎啟動 Service 的參數內容,所以用 Any

1
2
verify(mSpyService, times(1))
    .startForeground(Mockito.anyInt(), Mockito.<Notification>any());

如果想測試 method call 的物件參數是不是符合預期,好比 Notification 的顏色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
verify(mSpyService, times(1)).startForeground(
    Mockito.anyInt(),
    Mockito.argThat(new ArgumentMatcher<Notification>() {
        @Override
        public boolean matches(Object argument) {
            Notification notification = (Notification) argument;
            // put assertion here!
            Assert.assertEquals(notification.color, 0xFF0000);
            return true;
        }
    }));

如果只是想測試簡單的 primitive,好比 Service.stopSelf(int)

1
verify(mSpyService, times(1)).stopSelf(eq(123));

剩下的,有想到啥再繼續從這篇裡面補完吧